diff --git a/src/libslic3r/BeltGCode.cpp b/src/libslic3r/BeltGCode.cpp index 8c8c3d4392..8184692862 100644 --- a/src/libslic3r/BeltGCode.cpp +++ b/src/libslic3r/BeltGCode.cpp @@ -3,8 +3,6 @@ #include "BeltTransform.hpp" #include "Print.hpp" -#include - namespace Slic3r { void BeltGCode::init_belt_writer(Print &print, bool is_bbl_printers) @@ -18,14 +16,6 @@ void BeltGCode::init_belt_writer(Print &print, bool is_bbl_printers) belt_writer->set_belt_back_transform(print.config()); belt_writer->set_machine_frame_transform(print.config()); m_writer = std::move(belt_writer); - - // Per-axis origin snap config. - m_origin_snap[0] = print.config().belt_origin_snap_x.value; - m_origin_snap[1] = print.config().belt_origin_snap_y.value; - m_origin_snap[2] = print.config().belt_origin_snap_z.value; - m_origin_snap_offset[0] = print.config().belt_origin_offset_x.value; - m_origin_snap_offset[1] = print.config().belt_origin_offset_y.value; - m_origin_snap_offset[2] = print.config().belt_origin_offset_z.value; } void BeltGCode::write_belt_header(GCodeOutputStream &file, const Print &print) @@ -64,103 +54,36 @@ void BeltGCode::write_belt_header(GCodeOutputStream &file, const Print &print) file.write_format("; belt_gcode_transform_order = %s\n", full_cfg.opt_serialize("belt_gcode_transform_order").c_str()); } -void BeltGCode::on_set_origin(const PrintObject *obj, const Point &inst_shift) +void BeltGCode::on_set_origin(const PrintObject * /*obj*/, const Point & /*inst_shift*/) { // Global pre-slice mode: adjust origin using computed correction. // Transform the origin through the belt pipeline so that // back_transform(T * origin) = origin (correct machine position). - // This replaces the bbox-based axis snap with an exact formula. // // Flags that trigger this path: // belt_preslice_global — full pipeline (rotation * remap) is global // preslice_remap_global — only the pre-slice remap is global // belt_slice_rotation_global — slicing rotation treated as global (matches // the per-instance Z-offset added in PrintObjectSlice.cpp) - // The XY origin adjustment uses the FULL forward transform either way, - // because the back_transform applied during G-code emission is always the - // inverse of the full pipeline. + // The XY origin adjustment uses the FULL forward transform, because the + // back_transform applied during G-code emission is always the inverse of + // the full pipeline. bool use_global = m_config.belt_preslice_global.value || (m_config.preslice_remap_global.value && BeltTransformPipeline::has_preslice_remap(m_config)) || (m_config.belt_slice_rotation_global.value && m_config.belt_slice_rotation.value != BeltRotationAxis::None && std::abs(m_config.belt_slice_rotation_angle.value) > EPSILON); - if (use_global && m_config.belt_printer.value) { - auto *belt_writer = dynamic_cast(m_writer.get()); - if (belt_writer) { - // The per-object lift (z_shift_val = max(0, -m_belt_min_z)) added by - // BeltSliceStrategy::apply_to_trafo is already compensated inside - // global_z_offset (via the belt_z_shift term in PrintObjectSlice.cpp). - // Snap was previously used here for the same purpose, but with both - // active the lift gets subtracted twice. Clear any leftover snap - // state from a prior instance. - for (int a = 0; a < 3; ++a) - belt_writer->set_origin_snap(a, false, 0., 0.); - } - - // Adjust origin: transform through belt forward pipeline so that - // the back-transform correctly recovers model-space positions. - Transform3d T = BeltTransformPipeline::build_forward_transform(m_config); - Vec2d cur_origin = this->origin(); - Vec3d origin3d(cur_origin.x(), cur_origin.y(), 0.); - Vec3d adjusted = T.linear() * origin3d; - this->set_origin(Vec2d(adjusted.x(), adjusted.y())); - return; - } - - if (!m_origin_snap[0] && !m_origin_snap[1] && !m_origin_snap[2]) + if (!use_global || !m_config.belt_printer.value) return; - auto *belt_writer = dynamic_cast(m_writer.get()); - if (!belt_writer) - return; - - // Clear existing snap so to_machine_coords gives raw machine coords for bbox computation. - for (int a = 0; a < 3; ++a) - belt_writer->set_origin_snap(a, false, 0., 0.); - - // Reconstruct the belt pipeline transform for this object. - Transform3d belt = BeltTransformPipeline::build_forward_transform(m_config); - - // Z-shift - double zs = (obj->belt_min_z() < 0.) ? -obj->belt_min_z() : 0.; - if (zs > 0.) { - Transform3d zsh = Transform3d::Identity(); - zsh.matrix()(2, 3) = zs; - belt = zsh * belt; - } - - // Full transform: belt * trafo_centered - Transform3d full = belt * obj->trafo_centered(); - - // Instance shift in slicer space + global Z offset - Vec3d shift(unscale(inst_shift.x()), - unscale(inst_shift.y()), - obj->belt_global_z_offset()); - - // Compute this instance's bbox min in the Cartesian frame (post back_transform - // + axis_remap, before machine_frame_transform). Using to_cartesian instead of - // to_machine_coords ensures the 8 axis-aligned bbox corners coincide with the - // geometry's extreme points — a property that breaks under shear, which would - // mis-normalize non-cubic shapes (inverted cone, benchy) by their bbox-volume - // corners rather than their actual lowest geometry point. - BoundingBoxf3 bb = obj->model_object()->raw_bounding_box(); - Vec3d mn = bb.min.cast(), mx = bb.max.cast(); - Vec3d inst_min(std::numeric_limits::max(), - std::numeric_limits::max(), - std::numeric_limits::max()); - for (int i = 0; i < 8; ++i) { - Vec3d c((i & 1) ? mx.x() : mn.x(), - (i & 2) ? mx.y() : mn.y(), - (i & 4) ? mx.z() : mn.z()); - Vec3d mc = belt_writer->to_cartesian(full * c + shift); - for (int a = 0; a < 3; ++a) - inst_min[a] = std::min(inst_min[a], mc[a]); - } - - // Update writer snap for each enabled axis - for (int a = 0; a < 3; ++a) - belt_writer->set_origin_snap(a, m_origin_snap[a], m_origin_snap_offset[a], inst_min[a]); + // Adjust origin: transform through belt forward pipeline so that + // the back-transform correctly recovers model-space positions. + Transform3d T = BeltTransformPipeline::build_forward_transform(m_config); + Vec2d cur_origin = this->origin(); + Vec3d origin3d(cur_origin.x(), cur_origin.y(), 0.); + Vec3d adjusted = T.linear() * origin3d; + this->set_origin(Vec2d(adjusted.x(), adjusted.y())); } } // namespace Slic3r diff --git a/src/libslic3r/BeltGCode.hpp b/src/libslic3r/BeltGCode.hpp index 682deb7d65..2a3718b49f 100644 --- a/src/libslic3r/BeltGCode.hpp +++ b/src/libslic3r/BeltGCode.hpp @@ -9,7 +9,7 @@ namespace Slic3r { // Inherits from GCode and overrides virtual hooks to: // - Create a BeltGCodeWriter instead of a plain GCodeWriter // - Write belt configuration to the G-code header -// - Update per-axis origin snap when switching instances +// - Adjust the origin for global pre-slice transforms when switching instances // - Disable arc fitting (G2/G3 not supported on belt printers) class BeltGCode : public GCode { @@ -18,11 +18,6 @@ protected: void write_belt_header(GCodeOutputStream &file, const Print &print) override; void on_set_origin(const PrintObject *obj, const Point &inst_shift) override; bool should_disable_arc_fitting() const override { return true; } - -private: - // Per-axis origin snap config (set during init, used in on_set_origin). - bool m_origin_snap[3] = {false, false, false}; - double m_origin_snap_offset[3] = {0., 0., 0.}; }; } // namespace Slic3r diff --git a/src/libslic3r/BeltGCodeWriter.cpp b/src/libslic3r/BeltGCodeWriter.cpp index 9f1f32a375..a2322c9243 100644 --- a/src/libslic3r/BeltGCodeWriter.cpp +++ b/src/libslic3r/BeltGCodeWriter.cpp @@ -35,37 +35,14 @@ void BeltGCodeWriter::set_machine_frame_transform(const PrintConfig &config) m_machine_frame_transform.init_from_config(config); } -void BeltGCodeWriter::set_origin_snap(int axis, bool enable, double offset, double bbox_min) -{ - if (axis >= 0 && axis < 3) { - m_origin_snap[axis] = enable; - m_origin_offset[axis] = offset; - m_origin_bbox_min[axis] = bbox_min; - } -} - -Vec3d BeltGCodeWriter::to_cartesian(const Vec3d &pos) const -{ - // back_transform → axis_remap, no origin_snap, no machine_frame_transform. - return apply_axis_remap(m_belt_back_transform.apply(pos)); -} - Vec3d BeltGCodeWriter::to_machine_coords(const Vec3d &pos) const { // Step 1+2: To Cartesian (back_transform + axis_remap). Vec3d after_back = m_belt_back_transform.apply(pos); Vec3d result = apply_axis_remap(after_back); Vec3d after_remap = result; - // Step 3: Per-axis origin snap (computed in the Cartesian frame). - for (int i = 0; i < 3; ++i) - if (m_origin_snap[i]) - result[i] -= (m_origin_bbox_min[i] - m_origin_offset[i]); - Vec3d after_snap = result; - // Step 4: Machine-frame transform (gcode_shear / gcode_scale) - // applied LAST so it acts as a global linear transform on the placed coords. - // Order matters: putting it before origin_snap would feed sheared bbox corners - // into the snap's per-object min calculation, mis-normalizing non-cubic geometries - // (the corners of the original bbox aren't extreme points of the sheared shape). + // Step 3: Machine-frame transform (belt frame tilt) applied LAST so it acts + // as a global linear transform on the placed coords. Vec3d final = m_machine_frame_transform.apply(result); // [BELT-DEBUG] One-shot log per layer transition (i.e. when the input Z @@ -80,7 +57,6 @@ Vec3d BeltGCodeWriter::to_machine_coords(const Vec3d &pos) const << " slicer_in=(" << pos.x() << "," << pos.y() << "," << pos.z() << ")" << " after_back=(" << after_back.x() << "," << after_back.y() << "," << after_back.z() << ")" << " after_remap=(" << after_remap.x() << "," << after_remap.y() << "," << after_remap.z() << ")" - << " after_snap=(" << after_snap.x() << "," << after_snap.y() << "," << after_snap.z() << ")" << " final=(" << final.x() << "," << final.y() << "," << final.z() << ")" << " mft_active=" << m_machine_frame_transform.is_active() << " back_active=" << m_belt_back_transform.is_active(); diff --git a/src/libslic3r/BeltGCodeWriter.hpp b/src/libslic3r/BeltGCodeWriter.hpp index e9d4af0f3a..30159f4f33 100644 --- a/src/libslic3r/BeltGCodeWriter.hpp +++ b/src/libslic3r/BeltGCodeWriter.hpp @@ -11,8 +11,8 @@ class FirstLayerPlane; // Belt-printer-specific GCode writer. // // Inherits from GCodeWriter and overrides movement methods to apply -// coordinate transformation (back-transform, axis remap, origin snap) -// and emit coupled XYZ moves (Y and Z are coupled due to belt tilt). +// coordinate transformation (back-transform, axis remap, machine-frame +// transform) and emit coupled XYZ moves (Y and Z are coupled due to belt tilt). class BeltGCodeWriter : public GCodeWriter { public: @@ -21,12 +21,7 @@ public: // Belt configuration (axis remap is inherited from GCodeWriter) void set_belt_back_transform(const PrintConfig &config); void set_machine_frame_transform(const PrintConfig &config); - void set_origin_snap(int axis, bool enable, double offset, double bbox_min); Vec3d to_machine_coords(const Vec3d &pos) const; - // back_transform + axis_remap only (no origin_snap, no machine_frame_transform). - // Used by on_set_origin for bbox computation in the Cartesian frame, where - // axis-aligned bbox corners coincide with the geometry's extreme points. - Vec3d to_cartesian(const Vec3d &pos) const; // First-layer plane: when set to a non-null active evaluator, travel // speed selection consults the plane per-move and uses @@ -52,9 +47,6 @@ protected: private: BeltBackTransform m_belt_back_transform; MachineFrameTransform m_machine_frame_transform; - bool m_origin_snap[3] = {false, false, false}; - double m_origin_offset[3] = {0., 0., 0.}; - double m_origin_bbox_min[3] = {0., 0., 0.}; // Borrowed pointer; lifetime owned by GCode. null = inactive. const FirstLayerPlane *m_first_layer_plane = nullptr; double m_first_layer_thickness_mm = 0.; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 694cd284e3..9b514bb291 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1339,9 +1339,6 @@ static std::vector s_Preset_printer_options { "belt_gcode_transform_order", "belt_preslice_global", "first_layer_plane", "first_layer_plane_offset", "first_layer_plane_thickness", - "belt_origin_snap_x", "belt_origin_offset_x", - "belt_origin_snap_y", "belt_origin_offset_y", - "belt_origin_snap_z", "belt_origin_offset_z", "belt_support_floor_offset", "belt_support_floor_mode", "belt_support_z_offset_mode", "gcode_flavor", "fan_kickstart", "part_cooling_fan_min_pwm", "fan_speedup_time", "fan_speedup_overhangs", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index f55dd31fc1..099a592509 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -112,9 +112,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "gcode_scale_y", "gcode_scale_y_angle", "gcode_scale_z", "gcode_scale_z_angle", "belt_gcode_transform_order", - "belt_origin_snap_x", "belt_origin_offset_x", - "belt_origin_snap_y", "belt_origin_offset_y", - "belt_origin_snap_z", "belt_origin_offset_z", //BBS "additional_cooling_fan_speed", "reduce_crossing_wall", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index c1c411c7b6..cdb2ec1d5d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -6782,31 +6782,6 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(-1.0)); - auto add_belt_origin_snap = [this](const char *key_snap, const char *key_offset, - const char *axis_label) { - auto def = this->add(key_snap, coBool); - def->label = L(axis_label); - def->category = L("Printable space"); - std::string tip = std::string("Shift G-code output so the object's bounding box minimum on machine ") - + axis_label + " equals the offset value."; - def->tooltip = L(tip); - def->mode = comExpert; - def->set_default_value(new ConfigOptionBool(false)); - - def = this->add(key_offset, coFloat); - def->label = L("Offset"); - def->category = L("Printable space"); - def->tooltip = L("Target coordinate for the bounding box minimum on this machine axis."); - def->sidetext = L("mm"); - def->min = -10000; - def->max = 10000; - def->mode = comExpert; - def->set_default_value(new ConfigOptionFloat(0)); - }; - add_belt_origin_snap("belt_origin_snap_x", "belt_origin_offset_x", "X"); - add_belt_origin_snap("belt_origin_snap_y", "belt_origin_offset_y", "Y"); - add_belt_origin_snap("belt_origin_snap_z", "belt_origin_offset_z", "Z"); - // Belt support floor debug controls def = this->add("belt_support_floor_offset", coFloat); def->label = L("Support Floor Z offset"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 4a53aa7ac2..a31179cd9b 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1619,12 +1619,6 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionEnum, first_layer_plane)) ((ConfigOptionFloat, first_layer_plane_offset)) ((ConfigOptionFloat, first_layer_plane_thickness)) - ((ConfigOptionBool, belt_origin_snap_x)) - ((ConfigOptionFloat, belt_origin_offset_x)) - ((ConfigOptionBool, belt_origin_snap_y)) - ((ConfigOptionFloat, belt_origin_offset_y)) - ((ConfigOptionBool, belt_origin_snap_z)) - ((ConfigOptionFloat, belt_origin_offset_z)) ((ConfigOptionFloat, belt_support_floor_offset)) ((ConfigOptionEnum, belt_support_floor_mode)) ((ConfigOptionEnum, belt_support_z_offset_mode)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index bcbcce1d66..4027a671e7 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -4535,24 +4535,6 @@ void TabPrinter::build_fff() line.append_option(belt_og->get_option("first_layer_plane_thickness")); belt_og->append_line(line); } - { - Line line = { L("Origin snap X"), L("Snap object bbox min X to offset in G-code output") }; - line.append_option(belt_og->get_option("belt_origin_snap_x")); - line.append_option(belt_og->get_option("belt_origin_offset_x")); - belt_og->append_line(line); - } - { - Line line = { L("Origin snap Y"), L("Snap object bbox min Y to offset in G-code output") }; - line.append_option(belt_og->get_option("belt_origin_snap_y")); - line.append_option(belt_og->get_option("belt_origin_offset_y")); - belt_og->append_line(line); - } - { - Line line = { L("Origin snap Z"), L("Snap object bbox min Z to offset in G-code output") }; - line.append_option(belt_og->get_option("belt_origin_snap_z")); - line.append_option(belt_og->get_option("belt_origin_offset_z")); - belt_og->append_line(line); - } // Support floor: split across lines so each setting's own mode controls // its visibility (floor_mode = Develop, floor_offset = Advanced, z_offset_mode = Expert). belt_og->append_single_option_line("belt_support_floor_offset"); @@ -5591,8 +5573,6 @@ void TabPrinter::toggle_options() toggle_line("belt_printer_infinite_y", is_belt); // Belt tilt: the sole mesh-side belt transform (visible by default in belt mode). toggle_line("belt_slice_rotation", is_belt); - for (auto el : {"belt_origin_snap_x", "belt_origin_snap_y", "belt_origin_snap_z"}) - toggle_line(el, is_belt); // Remap, back-transform, and global mesh-transforms toggles are gated by belt // mode here; finer mode-based visibility (Advanced vs Expert) is handled by @@ -5643,11 +5623,6 @@ void TabPrinter::toggle_options() auto gscz = m_config->option>("gcode_scale_z")->value; toggle_option("gcode_scale_z_angle", is_belt && gscz != BeltScaleMode::None); - // Origin snap is superseded by belt_preslice_global - toggle_option("belt_origin_offset_x", is_belt && m_config->opt_bool("belt_origin_snap_x") && !belt_global); - toggle_option("belt_origin_offset_y", is_belt && m_config->opt_bool("belt_origin_snap_y") && !belt_global); - toggle_option("belt_origin_offset_z", is_belt && m_config->opt_bool("belt_origin_snap_z") && !belt_global); - // First-layer plane: visible alongside the rest of belt-printer settings. toggle_line("first_layer_plane", is_belt); toggle_option("first_layer_plane_offset", is_belt);