From 07fa713f0c6a199dd77b5601c6793fbae8081e3d Mon Sep 17 00:00:00 2001 From: Lam Wei Lun Date: Tue, 20 Oct 2026 18:24:20 +0800 Subject: [PATCH] Scale to Fit Print Volume: centre on the active plate The command centred the selection on the bed at the origin, so scaling a model that sat on plate 2 moved it back onto plate 1. Every plate shares the bed size, so only the centre differs: pass the active plate's centre and, for a circular bed, shift the print circle by it. --- src/slic3r/GUI/Plater.cpp | 8 +++++++- src/slic3r/GUI/Selection.cpp | 12 +++++++----- src/slic3r/GUI/Selection.hpp | 4 +++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3b224725f6..7b96d39eef 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -11034,7 +11034,13 @@ void Plater::priv::split_volume() void Plater::priv::scale_selection_to_fit_print_volume() { #if ENABLE_ENHANCED_PRINT_VOLUME_FIT - this->view3D->get_canvas3d()->get_selection().scale_to_fit_print_volume(this->bed.build_volume()); + const BuildVolume volume = this->bed.build_volume(); + // Every plate shares the bed size, but each sits at its own origin: fit onto the + // plate the selection is on instead of always onto the first one. + PartPlate* plate = this->partplate_list.get_curr_plate(); + const Vec3d bed_center = plate != nullptr ? plate->get_center_origin() : + Vec3d(volume.bed_center().x(), volume.bed_center().y(), 0.); + this->view3D->get_canvas3d()->get_selection().scale_to_fit_print_volume(volume, Vec2d(bed_center.x(), bed_center.y())); #else this->view3D->get_canvas3d()->get_selection().scale_to_fit_print_volume(*config); #endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 4d7f1591ee..be184cc980 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1496,7 +1496,7 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type } #if ENABLE_ENHANCED_PRINT_VOLUME_FIT -void Selection::scale_to_fit_print_volume(const BuildVolume& volume) +void Selection::scale_to_fit_print_volume(const BuildVolume& volume, const Vec2d& bed_center) { auto fit = [this](double s, Vec3d offset) { if (s <= 0.0 || s == 1.0) @@ -1526,7 +1526,7 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume) //wxGetApp().obj_manipul()->set_dirty(); }; - auto fit_rectangle = [this, fit](const BuildVolume& volume) { + auto fit_rectangle = [this, fit, &bed_center](const BuildVolume& volume) { const BoundingBoxf3 print_volume = volume.bounding_volume(); const Vec3d print_volume_size = print_volume.size(); @@ -1538,10 +1538,10 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume) const double sz = (box_size.z() != 0.0) ? print_volume_size.z() / box_size.z() : 0.0; if (sx != 0.0 && sy != 0.0 && sz != 0.0) - fit(std::min(sx, std::min(sy, sz)), print_volume.center() - get_bounding_box().center()); + fit(std::min(sx, std::min(sy, sz)), Vec3d(bed_center.x(), bed_center.y(), print_volume.center().z()) - get_bounding_box().center()); }; - auto fit_circle = [this, fit](const BuildVolume& volume) { + auto fit_circle = [this, fit, &bed_center](const BuildVolume& volume) { const Geometry::Circled& print_circle = volume.circle(); double print_circle_radius = unscale(print_circle.radius); @@ -1572,7 +1572,9 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume) const double s = std::min(print_circle_radius / circle_radius, volume.printable_height() / max_z); const Vec3d sel_center = get_bounding_box().center(); const Vec3d offset = s * (Vec3d(unscale(circle.center.x()), unscale(circle.center.y()), 0.5 * max_z) - sel_center); - const Vec3d print_center = { unscale(print_circle.center.x()), unscale(print_circle.center.y()), 0.5 * volume.printable_height() }; + // The active plate's bed is the same circle, moved by its centre. + const Vec3d plate_shift = Vec3d(bed_center.x() - volume.bed_center().x(), bed_center.y() - volume.bed_center().y(), 0.); + const Vec3d print_center = Vec3d(unscale(print_circle.center.x()), unscale(print_circle.center.y()), 0.5 * volume.printable_height()) + plate_shift; fit(s, print_center - (sel_center + offset)); }; diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index a02f01da00..cb5e7c4728 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -354,7 +354,9 @@ public: void flattening_rotate(const Vec3d& normal); void scale(const Vec3d& scale, TransformationType transformation_type); #if ENABLE_ENHANCED_PRINT_VOLUME_FIT - void scale_to_fit_print_volume(const BuildVolume& volume); + // bed_center is the centre of the plate the selection is on: every plate shares the + // bed size, but each sits at its own origin. + void scale_to_fit_print_volume(const BuildVolume& volume, const Vec2d& bed_center); #else void scale_to_fit_print_volume(const DynamicPrintConfig& config); #endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT