From c79970bedbcc542f448aeb8f29bf78d314f09cf3 Mon Sep 17 00:00:00 2001 From: Joseph Robertson <32232925+HarrierPigeon@users.noreply.github.com> Date: Tue, 19 May 2026 00:56:08 -0500 Subject: [PATCH] Clean Up Settings Interface, Update Generic Profile (#22) * clean up UI elements * further cleaning * final cleanup for first round of settings UI streamlining * update generic belt printer settings * fix generic again --- resources/profiles/Custom.json | 2 +- .../Custom/machine/fdm_belt_common.json | 10 +- src/libslic3r/PrintConfig.cpp | 126 +++++------ src/slic3r/GUI/Tab.cpp | 198 ++++++++++-------- 4 files changed, 181 insertions(+), 155 deletions(-) diff --git a/resources/profiles/Custom.json b/resources/profiles/Custom.json index 2119514211..fa683db8d6 100644 --- a/resources/profiles/Custom.json +++ b/resources/profiles/Custom.json @@ -1,6 +1,6 @@ { "name": "Custom Printer", - "version": "02.03.02.62", + "version": "02.03.02.65", "force_update": "0", "description": "My configurations", "machine_model_list": [ diff --git a/resources/profiles/Custom/machine/fdm_belt_common.json b/resources/profiles/Custom/machine/fdm_belt_common.json index 1ca314da0f..039c4745e0 100644 --- a/resources/profiles/Custom/machine/fdm_belt_common.json +++ b/resources/profiles/Custom/machine/fdm_belt_common.json @@ -84,15 +84,15 @@ ], "preslice_remap_y": "pos_z", "preslice_remap_z": "pos_y", - "preslice_remap_global": "1", "printer_extruder_id": [ "1" ], - "belt_origin_snap_y": "1", "belt_printer": "1", - "belt_preslice_global": "1", - "belt_shear_z": "pos_cot", - "belt_shear_z_angle": "30", + "belt_shear_z": "pos_tan", + "belt_shear_z_angle": "45", + "belt_scale_y": "inv_cos", + "gcode_shear_z": "pos_tan", + "gcode_scale_y": "inv_cos", "build_plate_tilt_x": "45", "purge_in_prime_tower": "0", "scan_first_layer": "0", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 665b11dcd7..e83edf5a8d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -6305,7 +6305,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = u8"\u00B0"; def->min = -90; def->max = 90; - def->mode = comAdvanced; + def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.)); def = this->add("build_plate_tilt_y", coFloat); @@ -6317,11 +6317,11 @@ void PrintConfigDef::init_fff_params() def->sidetext = u8"\u00B0"; def->min = -90; def->max = 90; - def->mode = comAdvanced; + def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.)); def = this->add("belt_printer", coBool); - def->label = L("Belt printer"); + def->label = L("Enable belt printing"); def->category = L("Printable space"); def->tooltip = L("Enable belt printer mode. Belt printers use a conveyor belt as the build surface, " "tilted at an angle (typically 45 degrees). The slicer will rotate the slicing plane " @@ -6351,7 +6351,8 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionBool(true)); // Per-axis shear controls for belt printer - auto add_belt_shear_mode = [this](const char *key, const char *label, BeltShearMode default_mode) { + auto add_belt_shear_mode = [this](const char *key, const char *label, BeltShearMode default_mode, + ConfigOptionMode mode = comAdvanced) { auto def = this->add(key, coEnum); def->label = L(label); def->category = L("Printable space"); @@ -6359,10 +6360,11 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values = {"none", "pos_cot", "neg_cot", "pos_tan", "neg_tan"}; def->enum_labels = {L("None"), L("+cot(α)"), L("-cot(α)"), L("+tan(α)"), L("-tan(α)")}; - def->mode = comAdvanced; + def->mode = mode; def->set_default_value(new ConfigOptionEnum(default_mode)); }; - auto add_belt_shear_angle = [this](const char *key, const char *label) { + auto add_belt_shear_angle = [this](const char *key, const char *label, + ConfigOptionMode mode = comAdvanced) { auto def = this->add(key, coFloat); def->label = L(label); def->category = L("Printable space"); @@ -6370,10 +6372,11 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("°"); def->min = 0.1; def->max = 89.9; - def->mode = comAdvanced; + def->mode = mode; def->set_default_value(new ConfigOptionFloat(45)); }; - auto add_belt_axis_enum = [this](const char *key, const char *label, const char *tooltip, BeltAxis default_axis) { + auto add_belt_axis_enum = [this](const char *key, const char *label, const char *tooltip, + BeltAxis default_axis, ConfigOptionMode mode = comAdvanced) { auto def = this->add(key, coEnum); def->label = L(label); def->category = L("Printable space"); @@ -6381,7 +6384,7 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values = {"x", "y", "z"}; def->enum_labels = {L("X"), L("Y"), L("Z")}; - def->mode = comAdvanced; + def->mode = mode; def->set_default_value(new ConfigOptionEnum(default_axis)); }; @@ -6390,27 +6393,28 @@ void PrintConfigDef::init_fff_params() def->label = L(label); def->category = L("Printable space"); def->tooltip = L("Apply shear in global coordinates (position-aware) rather than object-local coordinates."); - def->mode = comAdvanced; + def->mode = comExpert; def->set_default_value(new ConfigOptionBool(default_val)); }; - add_belt_shear_mode("belt_shear_x", "Function", BeltShearMode::None); - add_belt_shear_angle("belt_shear_x_angle", "Angle"); - add_belt_axis_enum("belt_shear_x_from", "From", "Source axis for X shear.", BeltAxis::Z); + add_belt_shear_mode ("belt_shear_x", "Function", BeltShearMode::None, comExpert); + add_belt_shear_angle("belt_shear_x_angle", "Angle", comExpert); + add_belt_axis_enum ("belt_shear_x_from", "From", "Source axis for X shear.", BeltAxis::Z, comExpert); add_belt_shear_global("belt_shear_x_global", "Global"); - add_belt_shear_mode("belt_shear_y", "Function", BeltShearMode::None); - add_belt_shear_angle("belt_shear_y_angle", "Angle"); - add_belt_axis_enum("belt_shear_y_from", "From", "Source axis for Y shear.", BeltAxis::Z); + add_belt_shear_mode ("belt_shear_y", "Function", BeltShearMode::None, comExpert); + add_belt_shear_angle("belt_shear_y_angle", "Angle", comExpert); + add_belt_axis_enum ("belt_shear_y_from", "From", "Source axis for Y shear.", BeltAxis::Z, comExpert); add_belt_shear_global("belt_shear_y_global", "Global"); - add_belt_shear_mode("belt_shear_z", "Function", BeltShearMode::PosTan); + add_belt_shear_mode ("belt_shear_z", "Function", BeltShearMode::PosTan); add_belt_shear_angle("belt_shear_z_angle", "Angle"); - add_belt_axis_enum("belt_shear_z_from", "From", "Source axis for Z shear.", BeltAxis::Y); + add_belt_axis_enum ("belt_shear_z_from", "From", "Source axis for Z shear.", BeltAxis::Y); add_belt_shear_global("belt_shear_z_global", "Global", true); // Per-axis scale controls for belt printer - auto add_belt_scale_mode = [this](const char *key, const char *label, BeltScaleMode default_mode) { + auto add_belt_scale_mode = [this](const char *key, const char *label, BeltScaleMode default_mode, + ConfigOptionMode mode = comAdvanced) { auto def = this->add(key, coEnum); def->label = L(label); def->category = L("Printable space"); @@ -6418,10 +6422,11 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values = {"none", "inv_sin", "inv_cos", "sin", "cos"}; def->enum_labels = {L("None"), L("1/sin(α)"), L("1/cos(α)"), L("sin(α)"), L("cos(α)")}; - def->mode = comAdvanced; + def->mode = mode; def->set_default_value(new ConfigOptionEnum(default_mode)); }; - auto add_belt_scale_angle = [this](const char *key, const char *label) { + auto add_belt_scale_angle = [this](const char *key, const char *label, + ConfigOptionMode mode = comAdvanced) { auto def = this->add(key, coFloat); def->label = L(label); def->category = L("Printable space"); @@ -6429,18 +6434,18 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("°"); def->min = 0.1; def->max = 89.9; - def->mode = comAdvanced; + def->mode = mode; def->set_default_value(new ConfigOptionFloat(45)); }; - add_belt_scale_mode("belt_scale_x", "Function", BeltScaleMode::None); - add_belt_scale_angle("belt_scale_x_angle", "Angle"); + add_belt_scale_mode ("belt_scale_x", "Function", BeltScaleMode::None, comExpert); + add_belt_scale_angle("belt_scale_x_angle", "Angle", comExpert); - add_belt_scale_mode("belt_scale_y", "Function", BeltScaleMode::None); + add_belt_scale_mode ("belt_scale_y", "Function", BeltScaleMode::None); add_belt_scale_angle("belt_scale_y_angle", "Angle"); - add_belt_scale_mode("belt_scale_z", "Function", BeltScaleMode::None); - add_belt_scale_angle("belt_scale_z_angle", "Angle"); + add_belt_scale_mode ("belt_scale_z", "Function", BeltScaleMode::None, comExpert); + add_belt_scale_angle("belt_scale_z_angle", "Angle", comExpert); auto add_belt_transform_order = [this](const char *key, const char *label, const char *tooltip) { auto def = this->add(key, coEnum); @@ -6450,8 +6455,8 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values = {"scale_then_shear", "shear_then_scale"}; def->enum_labels = {L("Scale, then shear"), L("Shear, then scale")}; - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionEnum(BeltTransformOrder::ScaleThenShear)); + def->mode = comExpert; + def->set_default_value(new ConfigOptionEnum(BeltTransformOrder::ShearThenScale)); }; add_belt_transform_order("belt_mesh_transform_order", "Mesh transform order", @@ -6461,7 +6466,8 @@ void PrintConfigDef::init_fff_params() "follows the same order so that it correctly inverts the mesh transform."); // G-code axis remap with sign - auto add_belt_remap = [this](const char *key, const char *label, const char *tooltip, RemapAxis default_axis) { + auto add_belt_remap = [this](const char *key, const char *label, const char *tooltip, + RemapAxis default_axis, ConfigOptionMode mode = comSimple) { auto def = this->add(key, coEnum); def->label = L(label); def->category = L("Printable space"); @@ -6469,7 +6475,7 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values = {"pos_x", "pos_y", "pos_z", "neg_x", "neg_y", "neg_z", "rev_x", "rev_y", "rev_z"}; def->enum_labels = {L("+X"), L("+Y"), L("+Z"), L("-X"), L("-Y"), L("-Z"), L("Rev X"), L("Rev Y"), L("Rev Z")}; - def->mode = comSimple; // Visibility controlled by toggle_line in Tab.cpp + def->mode = mode; // Visibility may also be gated by toggle_line in Tab.cpp def->set_default_value(new ConfigOptionEnum(default_axis)); }; @@ -6479,19 +6485,19 @@ void PrintConfigDef::init_fff_params() "your belt printer's physical bed plane. For a printer whose bed is in the XZ plane, " "set Y to +Z and Z to +Y (or -Y) to swap the vertical and belt-travel axes. " "Default +X: no change.", - RemapAxis::PosX); + RemapAxis::PosX, comExpert); add_belt_remap("preslice_remap_y", "Y", "Before slicing, which model-space axis becomes the slicer's Y axis. " "The slicer treats Y as one of the two horizontal bed axes. If your physical " "belt surface runs along the Z axis, map Y to +Z here so the slicer slices " "along the correct plane. Default +Y: no change.", - RemapAxis::PosY); + RemapAxis::PosY, comExpert); add_belt_remap("preslice_remap_z", "Z", "Before slicing, which model-space axis becomes the slicer's Z axis (layer stacking direction). " "The slicer builds layers upward along this axis. If your printer's layer-stacking " "direction is the physical Y axis, map Z to +Y (or -Y for inverted direction). " "Rev mode mirrors relative to the build volume maximum. Default +Z: no change.", - RemapAxis::PosZ); + RemapAxis::PosZ, comExpert); def = this->add("preslice_remap_global", coBool); def->label = L("Global"); @@ -6500,35 +6506,35 @@ void PrintConfigDef::init_fff_params() "Without this, the remap is applied locally around each object's center, so " "objects at different positions don't get a position-dependent contribution. " "Mirrors the per-axis 'Global' option on belt mesh shears, but for the remap."); - def->mode = comAdvanced; + def->mode = comExpert; def->set_default_value(new ConfigOptionBool(false)); - add_belt_remap("gcode_remap_x", "X", "Which slicing axis maps to machine X in G-code output. Applied AFTER slicing, during G-code generation.", RemapAxis::PosX); - add_belt_remap("gcode_remap_y", "Y", "Which slicing axis maps to machine Y in G-code output. Applied AFTER slicing, during G-code generation.", RemapAxis::PosY); - add_belt_remap("gcode_remap_z", "Z", "Which slicing axis maps to machine Z in G-code output. Applied AFTER slicing, during G-code generation.", RemapAxis::PosZ); + add_belt_remap("gcode_remap_x", "X", "Which slicing axis maps to machine X in G-code output. Applied AFTER slicing, during G-code generation.", RemapAxis::PosX, comExpert); + add_belt_remap("gcode_remap_y", "Y", "Which slicing axis maps to machine Y in G-code output. Applied AFTER slicing, during G-code generation.", RemapAxis::PosY, comExpert); + add_belt_remap("gcode_remap_z", "Z", "Which slicing axis maps to machine Z in G-code output. Applied AFTER slicing, during G-code generation.", RemapAxis::PosZ, comExpert); // Machine-frame G-code transforms: applied AFTER back-transform and gcode_remap, // before per-axis origin snap. Maps Cartesian G-code to the printer's physical machine frame. - add_belt_shear_mode ("gcode_shear_x", "Function", BeltShearMode::None); - add_belt_shear_angle("gcode_shear_x_angle", "Angle"); - add_belt_axis_enum ("gcode_shear_x_from", "From", "Source axis for X shear in the machine-frame stage.", BeltAxis::Z); + add_belt_shear_mode ("gcode_shear_x", "Function", BeltShearMode::None, comExpert); + add_belt_shear_angle("gcode_shear_x_angle", "Angle", comExpert); + add_belt_axis_enum ("gcode_shear_x_from", "From", "Source axis for X shear in the machine-frame stage.", BeltAxis::Z, comExpert); - add_belt_shear_mode ("gcode_shear_y", "Function", BeltShearMode::None); - add_belt_shear_angle("gcode_shear_y_angle", "Angle"); - add_belt_axis_enum ("gcode_shear_y_from", "From", "Source axis for Y shear in the machine-frame stage.", BeltAxis::Z); + add_belt_shear_mode ("gcode_shear_y", "Function", BeltShearMode::None, comExpert); + add_belt_shear_angle("gcode_shear_y_angle", "Angle", comExpert); + add_belt_axis_enum ("gcode_shear_y_from", "From", "Source axis for Y shear in the machine-frame stage.", BeltAxis::Z, comExpert); add_belt_shear_mode ("gcode_shear_z", "Function", BeltShearMode::None); add_belt_shear_angle("gcode_shear_z_angle", "Angle"); add_belt_axis_enum ("gcode_shear_z_from", "From", "Source axis for Z shear in the machine-frame stage.", BeltAxis::Y); - add_belt_scale_mode ("gcode_scale_x", "Function", BeltScaleMode::None); - add_belt_scale_angle("gcode_scale_x_angle", "Angle"); + add_belt_scale_mode ("gcode_scale_x", "Function", BeltScaleMode::None, comExpert); + add_belt_scale_angle("gcode_scale_x_angle", "Angle", comExpert); add_belt_scale_mode ("gcode_scale_y", "Function", BeltScaleMode::None); add_belt_scale_angle("gcode_scale_y_angle", "Angle"); - add_belt_scale_mode ("gcode_scale_z", "Function", BeltScaleMode::None); - add_belt_scale_angle("gcode_scale_z_angle", "Angle"); + add_belt_scale_mode ("gcode_scale_z", "Function", BeltScaleMode::None, comExpert); + add_belt_scale_angle("gcode_scale_z_angle", "Angle", comExpert); add_belt_transform_order("belt_gcode_transform_order", "G-code transform order", "Order in which the machine-frame shear and scale matrices are composed when " @@ -6554,8 +6560,8 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Reverse the shear/scale transform applied during slicing so G-code " "coordinates are in the machine's physical coordinate space. " "Requires at least one shear axis with global mode enabled."); - def->mode = comSimple; // Visibility controlled by toggle_line in Tab.cpp - def->set_default_value(new ConfigOptionBool(false)); + def->mode = comExpert; + def->set_default_value(new ConfigOptionBool(true)); def = this->add("belt_preslice_global", coBool); def->label = L("Global mesh transforms"); @@ -6563,8 +6569,8 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("When enabled, pre-slice belt transforms (remap, shear, scale) account for " "each object's bed position, producing correct machine coordinates without " "relying on origin snap. Each instance gets its own PrintObject."); - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionBool(false)); + def->mode = comExpert; + def->set_default_value(new ConfigOptionBool(true)); // First-layer plane: which surface defines "first layer" for fan / speed / // accel decisions. On belt printers the slicing-frame layer 0 is a tilted @@ -6583,11 +6589,11 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values = {"auto", "xy", "yz", "xz", "belt_shear"}; def->enum_labels = {L("Auto"), L("XY (machine bed)"), L("YZ"), L("XZ"), L("Belt shear plane")}; - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionEnum(FirstLayerPlaneMode::Auto)); + def->mode = comExpert; + def->set_default_value(new ConfigOptionEnum(FirstLayerPlaneMode::BeltShear)); def = this->add("first_layer_plane_offset", coFloat); - def->label = L("Plane offset"); + def->label = L("Belt plane offset"); def->category = L("Printable space"); def->tooltip = L("Shifts the first-layer plane along its normal (mm). For axis-aligned " "planes this is just a coordinate shift. Positive values move the plane " @@ -6619,7 +6625,7 @@ void PrintConfigDef::init_fff_params() 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 = comAdvanced; + def->mode = comExpert; def->set_default_value(new ConfigOptionBool(false)); def = this->add(key_offset, coFloat); @@ -6629,7 +6635,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = -10000; def->max = 10000; - def->mode = comAdvanced; + def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0)); }; add_belt_origin_snap("belt_origin_snap_x", "belt_origin_offset_x", "X"); @@ -6638,7 +6644,7 @@ void PrintConfigDef::init_fff_params() // Belt support floor debug controls def = this->add("belt_support_floor_offset", coFloat); - def->label = L("Floor Z offset"); + def->label = L("Support Floor Z offset"); def->category = L("Printable space"); def->tooltip = L("Shifts the computed belt floor up or down (mm). Negative values lower the floor, allowing more supports to survive. Use this to diagnose belt floor formula issues."); def->sidetext = L("mm"); @@ -6656,7 +6662,7 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values = {"none", "generator_only"}; def->enum_labels = {L("None"), L("Generator only")}; - def->mode = comAdvanced; + def->mode = comDevelop; def->set_default_value(new ConfigOptionEnum(BeltSupportFloorMode::GeneratorOnly)); } @@ -6669,7 +6675,7 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values = {"none", "unconditional", "raft_only"}; def->enum_labels = {L("None"), L("Unconditional"), L("Raft only")}; - def->mode = comAdvanced; + def->mode = comExpert; def->set_default_value(new ConfigOptionEnum(BeltSupportZOffsetMode::Unconditional)); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index e9356144ad..b0ee2c9435 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1268,6 +1268,13 @@ void Tab::update_mode() { m_mode = wxGetApp().get_mode(); + // toggle_options reads m_mode to gate Lines whose contents are mode-mixed + // (e.g., a multi-option row where some options are Advanced and some Expert): + // when all of a Line's options would be hidden, we hide the Line itself. + // Without refreshing here, the toggle_visible state stays stale across mode + // switches and Lines stay hidden. + toggle_options(); + update_visibility(); update_changed_tree_ui(); @@ -4448,75 +4455,77 @@ void TabPrinter::build_fff() //option.opt.full_width = true; //optgroup->append_single_option_line(option); optgroup->append_single_option_line("disable_m73", "printer_basic_information_advanced#disable-set-remaining-print-time"); - optgroup->append_single_option_line("build_plate_tilt_x"); - optgroup->append_single_option_line("build_plate_tilt_y"); - optgroup->append_single_option_line("belt_printer"); - optgroup->append_single_option_line("belt_printer_angle"); - optgroup->append_single_option_line("belt_printer_infinite_y"); + + // Belt printer: dedicated section. Everything except the "Enable belt printing" + // checkbox is hidden when belt_printer is off (see TabPrinter::toggle_options). + auto belt_og = page->new_optgroup(L("Belt printer"), L"param_advanced"); + belt_og->append_single_option_line("belt_printer"); + belt_og->append_single_option_line("belt_printer_angle"); + belt_og->append_single_option_line("belt_printer_infinite_y"); // Per-axis shear: group mode + angle + source on one row per axis { Line line = { L("Mesh shear X"), L("Shear applied to the X axis before slicing") }; - line.append_option(optgroup->get_option("belt_shear_x")); - line.append_option(optgroup->get_option("belt_shear_x_angle")); - line.append_option(optgroup->get_option("belt_shear_x_from")); - line.append_option(optgroup->get_option("belt_shear_x_global")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("belt_shear_x")); + line.append_option(belt_og->get_option("belt_shear_x_angle")); + line.append_option(belt_og->get_option("belt_shear_x_from")); + line.append_option(belt_og->get_option("belt_shear_x_global")); + belt_og->append_line(line); } { Line line = { L("Mesh shear Y"), L("Shear applied to the Y axis before slicing") }; - line.append_option(optgroup->get_option("belt_shear_y")); - line.append_option(optgroup->get_option("belt_shear_y_angle")); - line.append_option(optgroup->get_option("belt_shear_y_from")); - line.append_option(optgroup->get_option("belt_shear_y_global")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("belt_shear_y")); + line.append_option(belt_og->get_option("belt_shear_y_angle")); + line.append_option(belt_og->get_option("belt_shear_y_from")); + line.append_option(belt_og->get_option("belt_shear_y_global")); + belt_og->append_line(line); } { Line line = { L("Mesh shear Z"), L("Shear applied to the Z axis before slicing") }; - line.append_option(optgroup->get_option("belt_shear_z")); - line.append_option(optgroup->get_option("belt_shear_z_angle")); - line.append_option(optgroup->get_option("belt_shear_z_from")); - line.append_option(optgroup->get_option("belt_shear_z_global")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("belt_shear_z")); + line.append_option(belt_og->get_option("belt_shear_z_angle")); + line.append_option(belt_og->get_option("belt_shear_z_from")); + line.append_option(belt_og->get_option("belt_shear_z_global")); + belt_og->append_line(line); } { Line line = { L("Mesh scale X"), L("Scale applied to the X axis before slicing") }; - line.append_option(optgroup->get_option("belt_scale_x")); - line.append_option(optgroup->get_option("belt_scale_x_angle")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("belt_scale_x")); + line.append_option(belt_og->get_option("belt_scale_x_angle")); + belt_og->append_line(line); } { Line line = { L("Mesh scale Y"), L("Scale applied to the Y axis before slicing") }; - line.append_option(optgroup->get_option("belt_scale_y")); - line.append_option(optgroup->get_option("belt_scale_y_angle")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("belt_scale_y")); + line.append_option(belt_og->get_option("belt_scale_y_angle")); + belt_og->append_line(line); } { Line line = { L("Mesh scale Z"), L("Scale applied to the Z axis before slicing") }; - line.append_option(optgroup->get_option("belt_scale_z")); - line.append_option(optgroup->get_option("belt_scale_z_angle")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("belt_scale_z")); + line.append_option(belt_og->get_option("belt_scale_z_angle")); + belt_og->append_line(line); } - optgroup->append_single_option_line("belt_mesh_transform_order"); + belt_og->append_single_option_line("belt_mesh_transform_order"); { Line line = { L("Pre-slice axis remap"), L("Remap model axes before slicing so the slicer's coordinate system matches " "the physical bed orientation. For belt printers whose bed is NOT in the XY plane, " "use this to swap axes so layers are stacked in the correct physical direction.") }; - line.append_option(optgroup->get_option("preslice_remap_x")); - line.append_option(optgroup->get_option("preslice_remap_y")); - line.append_option(optgroup->get_option("preslice_remap_z")); - line.append_option(optgroup->get_option("preslice_remap_global")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("preslice_remap_x")); + line.append_option(belt_og->get_option("preslice_remap_y")); + line.append_option(belt_og->get_option("preslice_remap_z")); + line.append_option(belt_og->get_option("preslice_remap_global")); + belt_og->append_line(line); } { Line line = { L("G-code axis remap (post-slice)"), L("Remap slicing-frame axes to machine axes in G-code output. Applied AFTER slicing, during G-code generation.") }; - line.append_option(optgroup->get_option("gcode_remap_x")); - line.append_option(optgroup->get_option("gcode_remap_y")); - line.append_option(optgroup->get_option("gcode_remap_z")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("gcode_remap_x")); + line.append_option(belt_og->get_option("gcode_remap_y")); + line.append_option(belt_og->get_option("gcode_remap_z")); + belt_og->append_line(line); } - optgroup->append_single_option_line("belt_preslice_global"); - optgroup->append_single_option_line("gcode_back_transform"); + belt_og->append_single_option_line("belt_preslice_global"); + belt_og->append_single_option_line("gcode_back_transform"); { Line line = { L("First layer plane"), L("Reference plane used to decide which extrusions get first-layer " @@ -4524,42 +4533,49 @@ void TabPrinter::build_fff() "printers, Auto resolves to the tilted belt-shear plane so that " "first-layer treatment follows perpendicular distance from the belt " "surface, not slicing layer index.") }; - line.append_option(optgroup->get_option("first_layer_plane")); - line.append_option(optgroup->get_option("first_layer_plane_offset")); - line.append_option(optgroup->get_option("first_layer_plane_thickness")); - optgroup->append_line(line); + line.append_option(belt_og->get_option("first_layer_plane")); + line.append_option(belt_og->get_option("first_layer_plane_offset")); + 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(optgroup->get_option("belt_origin_snap_x")); - line.append_option(optgroup->get_option("belt_origin_offset_x")); - optgroup->append_line(line); + 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(optgroup->get_option("belt_origin_snap_y")); - line.append_option(optgroup->get_option("belt_origin_offset_y")); - optgroup->append_line(line); + 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(optgroup->get_option("belt_origin_snap_z")); - line.append_option(optgroup->get_option("belt_origin_offset_z")); - optgroup->append_line(line); - } - { - Line line = { L("Support floor"), L("Belt floor awareness for support generation and clipping") }; - line.append_option(optgroup->get_option("belt_support_floor_mode")); - line.append_option(optgroup->get_option("belt_support_floor_offset")); - line.append_option(optgroup->get_option("belt_support_z_offset_mode")); - optgroup->append_line(line); + 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"); + belt_og->append_single_option_line("belt_support_z_offset_mode"); + belt_og->append_single_option_line("belt_support_floor_mode"); // Machine-frame transforms: applied to G-code after back-transform and // gcode_remap, before per-axis origin snap. Maps Cartesian G-code into // the printer's physical machine frame. { auto mf = page->new_optgroup(L("Machine frame transforms"), L"param_advanced"); + { + Line line = { L("Post-gcode axis remap"), + L("Axis remap in the machine-frame stage. Applied AFTER gcode_remap, " + "to put coordinates into the printer's physical axis labelling.") }; + line.append_option(mf->get_option("post_gcode_remap_x")); + line.append_option(mf->get_option("post_gcode_remap_y")); + line.append_option(mf->get_option("post_gcode_remap_z")); + mf->append_line(line); + } { Line line = { L("G-code shear X"), L("Shear applied to the X axis in the machine-frame stage (after back-transform and gcode_remap).") }; line.append_option(mf->get_option("gcode_shear_x")); @@ -4600,15 +4616,6 @@ void TabPrinter::build_fff() mf->append_line(line); } mf->append_single_option_line("belt_gcode_transform_order"); - { - Line line = { L("Post-gcode axis remap"), - L("Axis remap in the machine-frame stage. Applied AFTER gcode_remap, " - "to put coordinates into the printer's physical axis labelling.") }; - line.append_option(mf->get_option("post_gcode_remap_x")); - line.append_option(mf->get_option("post_gcode_remap_y")); - line.append_option(mf->get_option("post_gcode_remap_z")); - mf->append_line(line); - } } option = optgroup->get_option("thumbnails"); @@ -4655,6 +4662,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("use_firmware_retraction", "printer_basic_information_advanced#use-firmware-retraction"); // optgroup->append_single_option_line("spaghetti_detector"); optgroup->append_single_option_line("time_cost", "printer_basic_information_advanced#time-cost"); + optgroup->append_single_option_line("build_plate_tilt_x"); + optgroup->append_single_option_line("build_plate_tilt_y"); optgroup = page->new_optgroup(L("Cooling Fan"), "param_cooling_fan"); Line line = Line{ L("Fan speed-up time"), optgroup->get_option("fan_speedup_time").opt.tooltip }; @@ -5580,24 +5589,33 @@ void TabPrinter::toggle_options() // Belt printer: show belt-specific settings only when belt_printer is enabled. bool is_belt = m_config->opt_bool("belt_printer"); + bool expert_or_above = (m_mode >= comExpert); toggle_line("belt_printer_angle", is_belt); toggle_line("belt_printer_infinite_y", is_belt); - for (auto el : {"belt_shear_x", "belt_shear_y", "belt_shear_z", - "belt_scale_x", "belt_scale_y", "belt_scale_z", - "belt_mesh_transform_order", + // Mesh shear/scale: only shear Z and scale Y are shown in Advanced; the others + // are Expert-only. Each Line packs all its options on one row, so toggle the + // Line here in addition to the per-option mode gating. + toggle_line("belt_shear_x", is_belt && expert_or_above); + toggle_line("belt_shear_y", is_belt && expert_or_above); + toggle_line("belt_shear_z", is_belt); + toggle_line("belt_scale_x", is_belt && expert_or_above); + toggle_line("belt_scale_y", is_belt); + toggle_line("belt_scale_z", is_belt && expert_or_above); + for (auto el : {"belt_mesh_transform_order", "belt_origin_snap_x", "belt_origin_snap_y", "belt_origin_snap_z"}) toggle_line(el, is_belt); - // Remap options: visible when belt mode is on OR when UI is in developer mode. - bool show_remap = is_belt || (m_mode >= comDevelop); + // Remap, back-transform, and global mesh-transforms toggles are gated by belt + // mode here; finer mode-based visibility (Advanced vs Expert) is handled by + // each option's ConfigOptionMode in PrintConfig.cpp. for (auto el : {"preslice_remap_x", "gcode_remap_x", "gcode_back_transform"}) - toggle_line(el, show_remap); - toggle_line("belt_preslice_global", show_remap); + toggle_line(el, is_belt); + toggle_line("belt_preslice_global", is_belt); bool belt_global = is_belt && m_config->opt_bool("belt_preslice_global"); // preslice_remap_global: superseded by belt_preslice_global - toggle_option("preslice_remap_global", show_remap && !belt_global); + toggle_option("preslice_remap_global", is_belt && !belt_global); // Gray out angle/from sub-options when their parent shear/scale mode is None. // Per-axis globals are superseded when belt_preslice_global is on. @@ -5626,10 +5644,14 @@ void TabPrinter::toggle_options() toggle_option("belt_scale_z_angle", is_belt && scz != BeltScaleMode::None); // Machine-frame transforms: shown only in belt mode. - for (auto el : {"gcode_shear_x", "gcode_shear_y", "gcode_shear_z", - "gcode_scale_x", "gcode_scale_y", "gcode_scale_z", - "belt_gcode_transform_order", - "post_gcode_remap_x"}) + // Mirror the Advanced/Expert split used for mesh shear/scale. + toggle_line("gcode_shear_x", is_belt && expert_or_above); + toggle_line("gcode_shear_y", is_belt && expert_or_above); + toggle_line("gcode_shear_z", is_belt); + toggle_line("gcode_scale_x", is_belt && expert_or_above); + toggle_line("gcode_scale_y", is_belt); + toggle_line("gcode_scale_z", is_belt && expert_or_above); + for (auto el : {"belt_gcode_transform_order", "post_gcode_remap_x"}) toggle_line(el, is_belt); auto gsx = m_config->option>("gcode_shear_x")->value; @@ -5659,14 +5681,12 @@ void TabPrinter::toggle_options() 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. - // The Auto default keeps legacy XY behavior on non-belt printers, so it's - // safe to also show it in the developer mode for non-belt printers. - bool show_first_layer_plane = is_belt || (m_mode >= comDevelop); - toggle_line("first_layer_plane", show_first_layer_plane); - toggle_option("first_layer_plane_offset", show_first_layer_plane); - toggle_option("first_layer_plane_thickness", show_first_layer_plane); + toggle_line("first_layer_plane", is_belt); + toggle_option("first_layer_plane_offset", is_belt); + toggle_option("first_layer_plane_thickness", is_belt); - toggle_line("belt_support_floor_mode", is_belt); + for (auto el : {"belt_support_floor_mode", "belt_support_floor_offset", "belt_support_z_offset_mode"}) + toggle_line(el, is_belt); }