diff --git a/resources/images/plate_imex_mode.svg b/resources/images/plate_imex_mode.svg new file mode 100644 index 0000000000..30a67cdf35 --- /dev/null +++ b/resources/images/plate_imex_mode.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/resources/images/plate_imex_mode_dark.svg b/resources/images/plate_imex_mode_dark.svg new file mode 100644 index 0000000000..981fd88447 --- /dev/null +++ b/resources/images/plate_imex_mode_dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/resources/images/plate_imex_mode_hover.svg b/resources/images/plate_imex_mode_hover.svg new file mode 100644 index 0000000000..9463e767df --- /dev/null +++ b/resources/images/plate_imex_mode_hover.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/resources/images/plate_imex_mode_hover_dark.svg b/resources/images/plate_imex_mode_hover_dark.svg new file mode 100644 index 0000000000..301fa995ab --- /dev/null +++ b/resources/images/plate_imex_mode_hover_dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index b7513ea240..4fbb00018d 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -333,7 +333,7 @@ static constexpr const char* FIRST_LAYER_PRINT_SEQUENCE_ATTR = "first_layer_prin static constexpr const char* OTHER_LAYERS_PRINT_SEQUENCE_ATTR = "other_layers_print_sequence"; static constexpr const char* OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR = "other_layers_print_sequence_nums"; static constexpr const char* SPIRAL_VASE_MODE = "spiral_mode"; -static constexpr const char* IXEX_PARALLEL_MODE_ATTR = "ixex_parallel_mode"; +static constexpr const char* IMEX_PARALLEL_MODE_ATTR = "imex_parallel_mode"; static constexpr const char* FILAMENT_MAP_MODE_ATTR = "filament_map_mode"; static constexpr const char* FILAMENT_MAP_ATTR = "filament_maps"; static constexpr const char* LIMIT_FILAMENT_MAP_ATTR = "limit_filament_maps"; @@ -4293,8 +4293,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) std::istringstream(value) >> std::boolalpha >> spiral_mode; m_curr_plater->config.set_key_value("spiral_mode", new ConfigOptionBool(spiral_mode)); } - else if (key == IXEX_PARALLEL_MODE_ATTR) { - m_curr_plater->config.set_key_value("ixex_parallel_mode", new ConfigOptionString(value)); + else if (key == IMEX_PARALLEL_MODE_ATTR) { + m_curr_plater->config.set_key_value("imex_parallel_mode", new ConfigOptionString(value)); } else if (key == FILAMENT_MAP_MODE_ATTR) { @@ -7778,9 +7778,9 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SPIRAL_VASE_MODE << "\" " << VALUE_ATTR << "=\"" << spiral_mode_opt->getBool() << "\"/>\n"; { - auto* ixex_mode_opt = plate_data->config.option("ixex_parallel_mode"); - if (ixex_mode_opt && !ixex_mode_opt->value.empty() && ixex_mode_opt->value != "primary") - stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << IXEX_PARALLEL_MODE_ATTR << "\" " << VALUE_ATTR << "=\"" << ixex_mode_opt->value << "\"/>\n"; + auto* imex_mode_opt = plate_data->config.option("imex_parallel_mode"); + if (imex_mode_opt && !imex_mode_opt->value.empty() && imex_mode_opt->value != "primary") + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << IMEX_PARALLEL_MODE_ATTR << "\" " << VALUE_ATTR << "=\"" << imex_mode_opt->value << "\"/>\n"; } //filament map related diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 87a0ee1342..ec249a6ae5 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3054,18 +3054,18 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato file.write(m_writer.set_chamber_temperature(max_chamber_temp, true)); // set chamber_temperature } - // iXex: inject mode G-code before machine_start_gcode so the carriage mode + // IDEX/IQEX: inject mode G-code before machine_start_gcode so the carriage mode // macro is active before any motion, homing, or probing in start G-code. - if (print.config().is_ixex.value && !print.objects().empty()) { - const std::string& ixex_mode = print.objects().front()->config().ixex_parallel_mode.value; - if (!ixex_mode.empty() && ixex_mode != "primary") { - const auto& mode_names = print.config().ixex_mode_names.values; - const auto& mode_gcodes = print.config().ixex_mode_gcodes.values; + if (print.config().is_imex.value && !print.objects().empty()) { + const std::string& imex_mode = print.objects().front()->config().imex_parallel_mode.value; + if (!imex_mode.empty() && imex_mode != "primary") { + const auto& mode_names = print.config().imex_mode_names.values; + const auto& mode_gcodes = print.config().imex_mode_gcodes.values; for (size_t i = 0; i < mode_names.size() && i < mode_gcodes.size(); ++i) { - if (mode_names[i] == ixex_mode && !mode_gcodes[i].empty()) { - std::string ixex_gcode = this->placeholder_parser_process( - "ixex_mode_gcode", mode_gcodes[i], initial_extruder_id); - file.writeln(ixex_gcode); + if (mode_names[i] == imex_mode && !mode_gcodes[i].empty()) { + std::string imex_gcode = this->placeholder_parser_process( + "imex_mode_gcode", mode_gcodes[i], initial_extruder_id); + file.writeln(imex_gcode); break; } } diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index adb56b90ac..fc28d8e5ca 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -961,8 +961,8 @@ static std::vector s_Preset_print_options { "enable_wrapping_detection", "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "scarf_joint_flow_ratio", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", "scarf_overhang_threshold", "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width","calib_flowrate_topinfill_special_order", - // iXex parallel print mode (per-print selection) - "ixex_parallel_mode", + // IDEX/IQEX parallel print mode (per-print selection) + "imex_parallel_mode", }; static std::vector s_Preset_filament_options {/*"filament_colour", */ "default_filament_colour", "required_nozzle_HRC", "filament_diameter", "pellet_flow_coefficient", "volumetric_speed_coefficients", "filament_type", @@ -1040,10 +1040,10 @@ static std::vector s_Preset_printer_options { "z_offset", "disable_m73", "preferred_orientation", "emit_machine_limits_to_gcode", "pellet_modded_printer", "support_multi_bed_types", "default_bed_type", "bed_mesh_min","bed_mesh_max","bed_mesh_probe_distance", "adaptive_bed_mesh_margin", "enable_long_retraction_when_cut","long_retractions_when_cut","retraction_distances_when_cut", "bed_temperature_formula", "nozzle_flush_dataset", - // iXex (independent X extruder) — printer capability and user-defined modes - "is_ixex", "ixex_gantry_count", "ixex_tools_per_gantry", "ixex_tool_layout", - "ixex_nozzle_clearance_x", "ixex_nozzle_clearance_y", "ixex_carriage_margin", "ixex_viz_theme", - "ixex_mode_names", "ixex_mode_active_tools", "ixex_mode_gcodes" + // IDEX/IQEX (independent X extruder) — printer capability and user-defined modes + "is_imex", "imex_gantry_count", "imex_tools_per_gantry", "imex_tool_layout", + "imex_nozzle_clearance_x", "imex_nozzle_clearance_y", "imex_carriage_margin", "imex_viz_theme", + "imex_mode_names", "imex_mode_active_tools", "imex_mode_gcodes" }; static std::vector s_Preset_sla_print_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 30b2ead516..b4978b1263 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5487,14 +5487,14 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(true)); - // iXex (independent X extruder) — parallel printing support for IDEX/IQEX printers - def = this->add("is_ixex", coBool); - def->label = L("iXex Printer"); - def->tooltip = L("Enable iXex (independent X extruder) support for IDEX/IQEX printers with multiple independent carriages."); + // IDEX/IQEX (independent X extruder) — parallel printing support for IDEX/IQEX printers + def = this->add("is_imex", coBool); + def->label = L("IDEX/IQEX Printer"); + def->tooltip = L("Enable IDEX/IQEX (independent X extruder) support for IDEX/IQEX printers with multiple independent carriages."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); - def = this->add("ixex_gantry_count", coInt); + def = this->add("imex_gantry_count", coInt); def->label = L("Gantry Count"); def->tooltip = L("Number of independent Y-axis gantries. 1 for IDEX/single-rail IQEX. 2 for dual-gantry systems (divides bed into rows)."); def->min = 1; @@ -5502,7 +5502,7 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionInt(1)); - def = this->add("ixex_tools_per_gantry", coInt); + def = this->add("imex_tools_per_gantry", coInt); def->label = L("Tools per Gantry"); def->tooltip = L("Number of independent toolheads per gantry along X. 2 for IDEX-style."); def->min = 1; @@ -5510,7 +5510,7 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionInt(2)); - def = this->add("ixex_tool_layout", coString); + def = this->add("imex_tool_layout", coString); def->label = L("Tool 0 Corner"); def->tooltip = L("Physical corner of the bed where tool T0 (index 0) is located. " "Determines how tool indices map to bed zones. " @@ -5518,7 +5518,7 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("front-left")); - def = this->add("ixex_nozzle_clearance_x", coFloat); + def = this->add("imex_nozzle_clearance_x", coFloat); def->label = L("Nozzle Clearance X"); def->tooltip = L("Distance (mm) from the nozzle to the collision-side carriage edge in X. Used to calculate the width of the collision exclusion strip at each X boundary."); def->sidetext = L("mm"); @@ -5526,7 +5526,7 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(30.0)); - def = this->add("ixex_nozzle_clearance_y", coFloat); + def = this->add("imex_nozzle_clearance_y", coFloat); def->label = L("Nozzle Clearance Y"); def->tooltip = L("Distance (mm) from the nozzle to the collision-side carriage edge in Y. Used to calculate the width of the collision exclusion strip at each Y boundary."); def->sidetext = L("mm"); @@ -5534,7 +5534,7 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(30.0)); - def = this->add("ixex_carriage_margin", coFloat); + def = this->add("imex_carriage_margin", coFloat); def->label = L("Safety Margin"); def->tooltip = L("Non-blocking advisory clearance strip (mm) drawn inside the primary zone at each carriage boundary. Parts placed within this strip will still slice; it is a visual reminder to leave extra clearance near the zone edge."); def->sidetext = L("mm"); @@ -5543,32 +5543,32 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.0)); - def = this->add("ixex_viz_theme", coString); + def = this->add("imex_viz_theme", coString); def->label = L("Visualization Theme"); - def->tooltip = L("Color theme for iXex bed zone visualization. Choose a colorblind-friendly theme if needed."); + def->tooltip = L("Color theme for IDEX/IQEX bed zone visualization. Choose a colorblind-friendly theme if needed."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("standard")); - def = this->add("ixex_parallel_mode", coString); - def->label = L("iXex Print Mode"); - def->tooltip = L("Name of the active iXex parallel print mode, or \"primary\" for single-carriage printing. Requires iXex Printer enabled in the Printer preset (Printer \u2192 iXex tab)."); + def = this->add("imex_parallel_mode", coString); + def->label = L("IDEX/IQEX Print Mode"); + def->tooltip = L("Name of the active IDEX/IQEX parallel print mode, or \"primary\" for single-carriage printing. Requires IDEX/IQEX Printer enabled in the Printer preset (Printer \u2192 IDEX/IQEX tab)."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("primary")); - def = this->add("ixex_mode_names", coStrings); - def->label = L("iXex Mode Names"); - def->tooltip = L("Display names for each user-defined iXex parallel print mode."); + def = this->add("imex_mode_names", coStrings); + def->label = L("IDEX/IQEX Mode Names"); + def->tooltip = L("Display names for each user-defined IDEX/IQEX parallel print mode."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionStrings()); - def = this->add("ixex_mode_active_tools", coStrings); - def->label = L("iXex Mode Active Tools"); - def->tooltip = L("Tool role assignments for each mode. Format: \"idx:P,idx:C,idx:M\" where P=Primary, C=Copy, M=Mirror (e.g. \"0:P,1:C,2:M,3:M\"). Managed by the iXex Modes editor in the Printer preset."); + def = this->add("imex_mode_active_tools", coStrings); + def->label = L("IDEX/IQEX Mode Active Tools"); + def->tooltip = L("Tool role assignments for each mode. Format: \"idx:P,idx:C,idx:M\" where P=Primary, C=Copy, M=Mirror (e.g. \"0:P,1:C,2:M,3:M\"). Managed by the IDEX/IQEX Modes editor in the Printer preset."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionStrings()); - def = this->add("ixex_mode_gcodes", coStrings); - def->label = L("iXex Mode G-codes"); + def = this->add("imex_mode_gcodes", coStrings); + def->label = L("IDEX/IQEX Mode G-codes"); def->tooltip = L("G-code or macro call to inject at print start for each mode."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionStrings()); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index bdc384b023..f0b414e44f 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1035,8 +1035,8 @@ PRINT_CONFIG_CLASS_DEFINE( // Orca: internal use only ((ConfigOptionBool, calib_flowrate_topinfill_special_order)) // ORCA: special flag for flow rate calibration - // iXex parallel print mode (per-print selection, stores mode name or "primary") - ((ConfigOptionString, ixex_parallel_mode)) + // IDEX/IQEX parallel print mode (per-print selection, stores mode name or "primary") + ((ConfigOptionString, imex_parallel_mode)) ) // This object is mapped to Perl as Slic3r::Config::PrintRegion. @@ -1334,15 +1334,15 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionStrings, filament_start_gcode)) ((ConfigOptionBool, single_extruder_multi_material)) ((ConfigOptionBool, manual_filament_change)) - // iXex (independent X extruder) — parallel printing support for IDEX/IQEX printers - ((ConfigOptionBool, is_ixex)) - ((ConfigOptionInt, ixex_gantry_count)) - ((ConfigOptionInt, ixex_tools_per_gantry)) - ((ConfigOptionFloat, ixex_nozzle_clearance_x)) - ((ConfigOptionFloat, ixex_nozzle_clearance_y)) - ((ConfigOptionStrings, ixex_mode_names)) - ((ConfigOptionStrings, ixex_mode_active_tools)) - ((ConfigOptionStrings, ixex_mode_gcodes)) + // IDEX/IQEX (independent X extruder) — parallel printing support for IDEX/IQEX printers + ((ConfigOptionBool, is_imex)) + ((ConfigOptionInt, imex_gantry_count)) + ((ConfigOptionInt, imex_tools_per_gantry)) + ((ConfigOptionFloat, imex_nozzle_clearance_x)) + ((ConfigOptionFloat, imex_nozzle_clearance_y)) + ((ConfigOptionStrings, imex_mode_names)) + ((ConfigOptionStrings, imex_mode_active_tools)) + ((ConfigOptionStrings, imex_mode_gcodes)) ((ConfigOptionBool, single_extruder_multi_material_priming)) ((ConfigOptionBool, wipe_tower_no_sparse_layers)) ((ConfigOptionString, change_filament_gcode)) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 5163580c30..f64d9f5e4b 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -913,8 +913,8 @@ void GCodeViewer::SequentialView::render(const bool has_render_path, float legen // marker.set_world_offset(current_offset); marker.render(canvas_width, canvas_height, view_type); marker.render_position_window(viewer, canvas_width, canvas_height, view_type); - // iXex secondary carriage markers - for (auto& sec : m_ixex_secondary_markers) + // IDEX/IQEX secondary carriage markers + for (auto& sec : m_imex_secondary_markers) sec.render(canvas_width, canvas_height, view_type); } @@ -1511,7 +1511,7 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) m_sequential_view.marker.set_world_position(libvgcode::convert(curr_vertex.position)); m_sequential_view.marker.set_z_offset(m_z_offset + 0.5f); - // iXex: compute all carriage positions; update secondary nozzle markers; + // IDEX/IQEX: compute all carriage positions; update secondary nozzle markers; // carriage_box_draws is populated for toolhead footprint rendering after sequential_view.render(). // Okabe-Ito colorblind-safe palette — excludes orange (#E69F00) and sky blue (#56B4E9) // which are used by the bed zone fills, ensuring the markers contrast against the background. @@ -1523,41 +1523,41 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) }}; struct CarriageDraw { Vec3f pos; ColorRGBA color; float box_offset_x = 0.0f; float box_offset_y = 0.0f; }; std::vector carriage_box_draws; - float ixex_box_wx = 0.0f, ixex_box_wy = 0.0f; + float imex_box_wx = 0.0f, imex_box_wy = 0.0f; { PresetBundle* preset_bundle = wxGetApp().preset_bundle; - bool ixex_active = false; + bool imex_active = false; if (preset_bundle && m_sequential_view.m_show_marker) { const DynamicPrintConfig& printer_cfg = preset_bundle->printers.get_edited_preset().config; - auto* is_ixex_opt = printer_cfg.opt("is_ixex"); - if (is_ixex_opt && is_ixex_opt->value) { + auto* is_imex_opt = printer_cfg.opt("is_imex"); + if (is_imex_opt && is_imex_opt->value) { const DynamicPrintConfig& process_cfg = preset_bundle->prints.get_edited_preset().config; - auto* mode_opt = process_cfg.opt("ixex_parallel_mode"); + auto* mode_opt = process_cfg.opt("imex_parallel_mode"); std::string mode = mode_opt ? mode_opt->value : "primary"; // Per-plate mode overrides the process preset. if (auto* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate()) { - std::string plate_mode = plate->get_ixex_mode(); + std::string plate_mode = plate->get_imex_mode(); if (plate_mode != "primary") mode = plate_mode; } - if (mode != m_ixex_last_mode) { - m_sequential_view.m_ixex_secondary_markers.clear(); - m_ixex_last_mode = mode; + if (mode != m_imex_last_mode) { + m_sequential_view.m_imex_secondary_markers.clear(); + m_imex_last_mode = mode; } if (!mode.empty() && mode != "primary") { - auto* mode_names_opt = printer_cfg.opt("ixex_mode_names"); - auto* active_tools_opt = printer_cfg.opt("ixex_mode_active_tools"); + auto* mode_names_opt = printer_cfg.opt("imex_mode_names"); + auto* active_tools_opt = printer_cfg.opt("imex_mode_active_tools"); - auto* tpg_opt = printer_cfg.opt("ixex_tools_per_gantry"); - auto* wx_opt = printer_cfg.opt("ixex_nozzle_clearance_x"); - auto* wy_opt = printer_cfg.opt("ixex_nozzle_clearance_y"); + auto* tpg_opt = printer_cfg.opt("imex_tools_per_gantry"); + auto* wx_opt = printer_cfg.opt("imex_nozzle_clearance_x"); + auto* wy_opt = printer_cfg.opt("imex_nozzle_clearance_y"); int tools_per_gantry = tpg_opt ? std::max(1, tpg_opt->value) : 1; - ixex_box_wx = wx_opt ? (float)wx_opt->value : 30.0f; - ixex_box_wy = wy_opt ? (float)wy_opt->value : 30.0f; + imex_box_wx = wx_opt ? (float)wx_opt->value : 30.0f; + imex_box_wy = wy_opt ? (float)wy_opt->value : 30.0f; - // Parse "idx:P/C/M" format — matches PartPlate::calc_ixex_zones() exactly. + // Parse "idx:P/C/M" format — matches PartPlate::calc_imex_zones() exactly. // Primary = state 1 (P), Copy = 2 (C), Mirror = 3 (M). // Inactive tools (state 0) are not included in the stored string. int pri_tool = -1; @@ -1594,21 +1594,21 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) int sec_count = (int)sec_tool_ids.size(); if (sec_count > 0) { - ixex_active = true; + imex_active = true; // Lazy init secondary nozzle markers - if ((int)m_sequential_view.m_ixex_secondary_markers.size() != sec_count) { - m_sequential_view.m_ixex_secondary_markers.resize(sec_count); + if ((int)m_sequential_view.m_imex_secondary_markers.size() != sec_count) { + m_sequential_view.m_imex_secondary_markers.resize(sec_count); for (int i = 0; i < sec_count; ++i) { - m_sequential_view.m_ixex_secondary_markers[i].init(m_marker_filename); - m_sequential_view.m_ixex_secondary_markers[i].set_color( + m_sequential_view.m_imex_secondary_markers[i].init(m_marker_filename); + m_sequential_view.m_imex_secondary_markers[i].set_color( s_carriage_colors[(i + 1) % s_carriage_colors.size()]); } } // Bed X and Y bounds — read from the current plate's shape, which is // in world/GL coordinates (same space as curr_vertex.position), and is - // the exact same source used by PartPlate::calc_ixex_zones(). + // the exact same source used by PartPlate::calc_imex_zones(). float bed_x_min, bed_x_max, bed_y_min, bed_y_max; { PartPlate* curr_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); @@ -1633,12 +1633,12 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) } } - auto* gc_opt = printer_cfg.opt("ixex_gantry_count"); + auto* gc_opt = printer_cfg.opt("imex_gantry_count"); int gantry_count = gc_opt ? std::max(1, gc_opt->value) : 1; - // Apply the same flip logic as PartPlate::calc_ixex_zones() so physical + // Apply the same flip logic as PartPlate::calc_imex_zones() so physical // grid positions match the bed zone visualization. - auto* layout_opt = printer_cfg.opt("ixex_tool_layout"); + auto* layout_opt = printer_cfg.opt("imex_tool_layout"); const std::string layout_str = layout_opt ? layout_opt->value : "front-left"; const bool flip_x = (layout_str == "front-right" || layout_str == "rear-right"); const bool flip_y = (layout_str == "rear-left" || layout_str == "rear-right"); @@ -1673,15 +1673,15 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) // Primary carriage box: nozzle sits at the collision-side edge. // Default to centered; override once we know which side the secondaries are on. - float pri_box_offset_x = (pri_phys_col == 0) ? 0.0f : -ixex_box_wx; // nozzle at inner edge (facing center of bed) - float pri_box_offset_y = -ixex_box_wy; // nozzle at high-Y edge by default (gantry always behind nozzle); override if secondary is behind + float pri_box_offset_x = (pri_phys_col == 0) ? 0.0f : -imex_box_wx; // nozzle at inner edge (facing center of bed) + float pri_box_offset_y = -imex_box_wy; // nozzle at high-Y edge by default (gantry always behind nozzle); override if secondary is behind for (int i = 0; i < sec_count; ++i) { int sc = phys_col_of(sec_tool_ids[i]); int sr = phys_row_of(sec_tool_ids[i]); if (sc > pri_phys_col) { pri_box_offset_x = 0.0f; } - else if (sc < pri_phys_col) { pri_box_offset_x = -ixex_box_wx; } + else if (sc < pri_phys_col) { pri_box_offset_x = -imex_box_wx; } if (sr > pri_phys_row) { pri_box_offset_y = 0.0f; } - else if (sr < pri_phys_row) { pri_box_offset_y = -ixex_box_wy; } + else if (sr < pri_phys_row) { pri_box_offset_y = -imex_box_wy; } } carriage_box_draws.push_back({ prim_pos, s_carriage_colors[0], pri_box_offset_x, pri_box_offset_y }); @@ -1719,8 +1719,8 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) } Vec3f sec_pos{ sec_x, sec_y, prim_pos.z() }; - m_sequential_view.m_ixex_secondary_markers[i].set_world_position(sec_pos); - m_sequential_view.m_ixex_secondary_markers[i].set_z_offset(m_z_offset + 0.5f); + m_sequential_view.m_imex_secondary_markers[i].set_world_position(sec_pos); + m_sequential_view.m_imex_secondary_markers[i].set_z_offset(m_z_offset + 0.5f); // X: copy tools move in sync with primary so they share the same // X-facing orientation. Mirror tools approach from the opposite side // so the nozzle sits at the collision-side edge. @@ -1728,16 +1728,16 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) if (sec_state == 2) { sec_box_offset_x = pri_box_offset_x; } else { - if (sec_phys_col > pri_phys_col) sec_box_offset_x = -ixex_box_wx; + if (sec_phys_col > pri_phys_col) sec_box_offset_x = -imex_box_wx; else if (sec_phys_col < pri_phys_col) sec_box_offset_x = 0.0f; else sec_box_offset_x = pri_box_offset_x; } // Y: always row-based — gantry is always behind nozzle regardless of // copy/mirror (a back-row copy still has its gantry at the back). float sec_box_offset_y; - if (sec_phys_row > pri_phys_row) sec_box_offset_y = -ixex_box_wy; + if (sec_phys_row > pri_phys_row) sec_box_offset_y = -imex_box_wy; else if (sec_phys_row < pri_phys_row) sec_box_offset_y = 0.0f; - else sec_box_offset_y = -ixex_box_wy; + else sec_box_offset_y = -imex_box_wy; carriage_box_draws.push_back({ sec_pos, s_carriage_colors[(i + 1) % s_carriage_colors.size()], sec_box_offset_x, sec_box_offset_y }); @@ -1746,28 +1746,28 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) } } } - if (!ixex_active) - m_sequential_view.m_ixex_secondary_markers.clear(); + if (!imex_active) + m_sequential_view.m_imex_secondary_markers.clear(); } // BBS fixed buttom margin. m_moves_slider.pos_y m_sequential_view.render(!m_no_render_path, legend_height, &m_viewer, m_viewer.get_current_vertex().gcode_id, canvas_width, canvas_height - bottom_margin * m_scale, right_margin * m_scale, m_viewer.get_view_type()); - // iXex: render toolhead footprint boxes for each active carriage. - // Each box is ixex_nozzle_clearance_x × ixex_nozzle_clearance_y, sitting above the nozzle tip. - if (!carriage_box_draws.empty() && ixex_box_wx > 0.0f && ixex_box_wy > 0.0f) { + // IDEX/IQEX: render toolhead footprint boxes for each active carriage. + // Each box is imex_nozzle_clearance_x × imex_nozzle_clearance_y, sitting above the nozzle tip. + if (!carriage_box_draws.empty() && imex_box_wx > 0.0f && imex_box_wy > 0.0f) { // Rebuild box mesh every frame — dimensions can change via config edit without a // G-code reload, so dimension-based caching isn't safe. // Mesh origin: nozzle at x=0, centered in Y, Z starts at nozzle tip level. // Per-carriage box_offset_x shifts the mesh left or right so the nozzle lands // at the correct (collision-side) edge. { - const float box_h = std::max(ixex_box_wx, ixex_box_wy); - indexed_triangle_set its = its_make_cube((double)ixex_box_wx, (double)ixex_box_wy, (double)box_h); + const float box_h = std::max(imex_box_wx, imex_box_wy); + indexed_triangle_set its = its_make_cube((double)imex_box_wx, (double)imex_box_wy, (double)box_h); // No vertex pre-shifting — box_offset_x/y in the per-carriage transform // positions the nozzle at the correct collision-side edge. - m_ixex_toolhead_box.reset(); - m_ixex_toolhead_box.init_from(its); + m_imex_toolhead_box.reset(); + m_imex_toolhead_box.init_from(its); } GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); @@ -1787,8 +1787,8 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); shader->set_uniform("view_normal_matrix", view_normal_matrix); - m_ixex_toolhead_box.set_color(draw.color); - m_ixex_toolhead_box.render(); + m_imex_toolhead_box.set_color(draw.color); + m_imex_toolhead_box.render(); } shader->stop_using(); glsafe(::glDisable(GL_BLEND)); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index ee3c1e1ec7..a8e5607048 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -150,7 +150,7 @@ public: }; Marker marker; - std::vector m_ixex_secondary_markers; // one per active secondary carriage in iXex mode + std::vector m_imex_secondary_markers; // one per active secondary carriage in IDEX/IQEX mode GCodeWindow gcode_window; float m_scale = 1.0; bool m_show_marker = false; @@ -205,8 +205,8 @@ private: ConfigOptionMode m_user_mode; bool m_fold = {false}; std::string m_marker_filename; // cached for lazy secondary marker init - std::string m_ixex_last_mode; // detect mode changes for secondary marker rebuild - GLModel m_ixex_toolhead_box; // shared box mesh for all carriage footprint overlays + std::string m_imex_last_mode; // detect mode changes for secondary marker rebuild + GLModel m_imex_toolhead_box; // shared box mesh for all carriage footprint overlays size_t m_extruders_count; std::vector m_filament_diameters; diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index b4ec570d00..218889a2f7 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -540,13 +540,13 @@ 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 + // When an IDEX/IQEX parallel mode is active, constrain auto-arrange to the primary zone only // and treat carriage collision strips as hard excluded regions. - // NOTE: m_ixex_primary_zone_box and ixex_collision_zones() are in global (world) coordinates + // NOTE: m_imex_primary_zone_box and imex_collision_zones() are in global (world) coordinates // because they are derived from m_shape which includes the plate origin offset. The arranger // always works in plate-local space (origin = 0,0), so we subtract the plate origin here. if (PartPlate* curr_plate = partplate_list.get_curr_plate()) { - if (auto pz = curr_plate->ixex_primary_zone()) { + if (auto pz = curr_plate->imex_primary_zone()) { Vec3d plate_origin = curr_plate->get_origin(); double ox = plate_origin.x(), oy = plate_origin.y(); BoundingBoxf pz_local(Vec2d(pz->min.x() - ox, pz->min.y() - oy), @@ -558,7 +558,7 @@ void ArrangeJob::process(Ctl &ctl) { scaled_pz.max.x(), scaled_pz.max.y() }, { scaled_pz.min.x(), scaled_pz.max.y() }, }; - for (const BoundingBoxf3& cz : curr_plate->ixex_collision_zones()) { + for (const BoundingBoxf3& cz : curr_plate->imex_collision_zones()) { Polygon poly({ { scaled(cz.min.x() - ox), scaled(cz.min.y() - oy) }, { scaled(cz.max.x() - ox), scaled(cz.min.y() - oy) }, @@ -572,7 +572,7 @@ void ArrangeJob::process(Ctl &ctl) ap.is_virt_object = true; ap.bed_idx = current_plate_index; ap.height = 1; - ap.name = "IXexCollisionZone"; + ap.name = "IMEXCollisionZone"; m_unselected.emplace_back(std::move(ap)); } } diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 88d3b4cf63..17447a6707 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -365,32 +365,32 @@ std::vector PartPlate::get_plate_wrapping_detection_area() const return std::vector(); } -std::string PartPlate::get_ixex_mode() const +std::string PartPlate::get_imex_mode() const { - if (m_config.has("ixex_parallel_mode")) { - auto* opt = m_config.option("ixex_parallel_mode"); + if (m_config.has("imex_parallel_mode")) { + auto* opt = m_config.option("imex_parallel_mode"); if (opt && !opt->value.empty()) return opt->value; } return "primary"; } -void PartPlate::set_ixex_mode(const std::string& mode) +void PartPlate::set_imex_mode(const std::string& mode) { if (mode.empty() || mode == "primary") { - m_config.erase("ixex_parallel_mode"); + m_config.erase("imex_parallel_mode"); } else { - m_config.set_key_value("ixex_parallel_mode", new ConfigOptionString(mode)); + m_config.set_key_value("imex_parallel_mode", new ConfigOptionString(mode)); } update_slice_result_valid_state(false); - m_ixex_zones_mode_cache = "\x01"; // force zone rebuild + m_imex_zones_mode_cache = "\x01"; // force zone rebuild } -void PartPlate::reset_ixex_mode() +void PartPlate::reset_imex_mode() { - m_config.erase("ixex_parallel_mode"); + m_config.erase("imex_parallel_mode"); update_slice_result_valid_state(false); - m_ixex_zones_mode_cache = "\x01"; + m_imex_zones_mode_cache = "\x01"; } void PartPlate::set_spiral_vase_mode(bool spiral_mode, bool as_global) @@ -484,30 +484,30 @@ void PartPlate::calc_exclude_triangles(const ExPolygon &poly) // Forward declaration (defined later in this file) static bool init_model_from_lines(GLModel &model, const Lines &lines, float z); -void PartPlate::calc_ixex_zones() +void PartPlate::calc_imex_zones() { - m_ixex_copy_zones.clear(); - m_ixex_mirror_zones.clear(); + m_imex_copy_zones.clear(); + m_imex_mirror_zones.clear(); // Clear blocking vectors at the top so early returns don't leave stale data. - m_ixex_secondary_zone_boxes.clear(); - m_ixex_collision_zones.clear(); - m_ixex_collision_overlay.clear(); - m_ixex_margin_overlay.clear(); - m_ixex_primary_zone_box = std::nullopt; + m_imex_secondary_zone_boxes.clear(); + m_imex_collision_zones.clear(); + m_imex_collision_overlay.clear(); + m_imex_margin_overlay.clear(); + m_imex_primary_zone_box = std::nullopt; if (!wxGetApp().preset_bundle) return; const DynamicPrintConfig& printer_cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; - auto* is_ixex_opt = printer_cfg.option("is_ixex"); - if (!is_ixex_opt || !is_ixex_opt->value) + auto* is_imex_opt = printer_cfg.option("is_imex"); + if (!is_imex_opt || !is_imex_opt->value) return; // Per-plate mode takes priority over the process preset. - std::string active_mode = get_ixex_mode(); + std::string active_mode = get_imex_mode(); if (active_mode == "primary") { const DynamicPrintConfig& process_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config; - auto* mode_opt = process_cfg.option("ixex_parallel_mode"); + auto* mode_opt = process_cfg.option("imex_parallel_mode"); if (mode_opt && !mode_opt->value.empty()) active_mode = mode_opt->value; } @@ -515,9 +515,9 @@ void PartPlate::calc_ixex_zones() return; // Grid dimensions and tool layout from printer config - auto* gantry_opt = printer_cfg.option("ixex_gantry_count"); - auto* tpg_opt = printer_cfg.option("ixex_tools_per_gantry"); - auto* layout_opt = printer_cfg.option("ixex_tool_layout"); + auto* gantry_opt = printer_cfg.option("imex_gantry_count"); + auto* tpg_opt = printer_cfg.option("imex_tools_per_gantry"); + auto* layout_opt = printer_cfg.option("imex_tool_layout"); int n_cols = tpg_opt ? std::max(1, tpg_opt->value) : 2; int n_rows = gantry_opt ? std::max(1, gantry_opt->value) : 1; @@ -541,8 +541,8 @@ void PartPlate::calc_ixex_zones() return; // nothing to dim with a single zone // Look up secondary tool indices (active in mode, but NOT the primary tool) - auto* names_opt = printer_cfg.option("ixex_mode_names"); - auto* tools_opt = printer_cfg.option("ixex_mode_active_tools"); + auto* names_opt = printer_cfg.option("imex_mode_names"); + auto* tools_opt = printer_cfg.option("imex_mode_active_tools"); std::string active_tools_str; if (names_opt && tools_opt) { for (size_t i = 0; i < names_opt->values.size(); ++i) { @@ -668,18 +668,18 @@ void PartPlate::calc_ixex_zones() for (const auto& b : make_boxes(cells)) push_zone_fill(vec, b.x0, b.x1, b.y0, b.y1); }; - push_expanded_fills(m_ixex_copy_zones, copy_cells); - push_expanded_fills(m_ixex_mirror_zones, mirror_cells); + push_expanded_fills(m_imex_copy_zones, copy_cells); + push_expanded_fills(m_imex_mirror_zones, mirror_cells); // --- Secondary zone blocking --- // Collect the expanded bounding boxes for all secondary (copy+mirror) zones. // check_outside() uses these to prevent objects being placed outside the primary zone. for (const auto& b : make_boxes(copy_cells)) - m_ixex_secondary_zone_boxes.push_back( + m_imex_secondary_zone_boxes.push_back( BoundingBoxf3(Vec3d(b.x0, b.y0, -1.0), Vec3d(b.x1, b.y1, 1e4))); for (const auto& b : make_boxes(mirror_cells)) - m_ixex_secondary_zone_boxes.push_back( + m_imex_secondary_zone_boxes.push_back( BoundingBoxf3(Vec3d(b.x0, b.y0, -1.0), Vec3d(b.x1, b.y1, 1e4))); // --- Carriage collision danger strips --- @@ -696,9 +696,9 @@ void PartPlate::calc_ixex_zones() // !has_row_sep → full bed height; has_row_sep → primary row only // !has_col_sep → full bed width; has_col_sep → primary column only - auto* cw_opt = printer_cfg.option("ixex_nozzle_clearance_x"); - auto* ch_opt = printer_cfg.option("ixex_nozzle_clearance_y"); - auto* mgn_opt = printer_cfg.option("ixex_carriage_margin"); + auto* cw_opt = printer_cfg.option("imex_nozzle_clearance_x"); + auto* ch_opt = printer_cfg.option("imex_nozzle_clearance_y"); + auto* mgn_opt = printer_cfg.option("imex_carriage_margin"); double carriage_w = cw_opt ? cw_opt->value : 0.0; double carriage_h = ch_opt ? ch_opt->value : 0.0; double margin = mgn_opt ? mgn_opt->value : 0.0; @@ -714,7 +714,7 @@ void PartPlate::calc_ixex_zones() if (!clipped.empty()) { GLModel m; if (init_model_from_poly(m, clipped.front(), GROUND_Z)) - m_ixex_margin_overlay.push_back(std::move(m)); + m_imex_margin_overlay.push_back(std::move(m)); } }; @@ -723,14 +723,14 @@ 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)); + m_imex_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) { BoundingBoxf3 box; box.min = Vec3d(sx0, sy0, -1.0); box.max = Vec3d(sx1, sy1, 1e4); - m_ixex_collision_zones.push_back(box); + m_imex_collision_zones.push_back(box); ExPolygon cell; cell.contour.append({ scale_(sx0), scale_(sy0) }); @@ -741,7 +741,7 @@ void PartPlate::calc_ixex_zones() if (!clipped.empty()) { GLModel m; if (init_model_from_poly(m, clipped.front(), GROUND_Z)) - m_ixex_collision_overlay.push_back(std::move(m)); + m_imex_collision_overlay.push_back(std::move(m)); } }; @@ -799,29 +799,29 @@ void PartPlate::calc_ixex_zones() } } -// Build a cache key from the current iXex config options, or "" if iXex is off. +// Build a cache key from the current IDEX/IQEX config options, or "" if IDEX/IQEX is off. // Reads per-plate mode from m_config first, falling back to the process preset. -std::string PartPlate::build_ixex_cache_key() const +std::string PartPlate::build_imex_cache_key() const { if (!wxGetApp().preset_bundle) return ""; const DynamicPrintConfig& printer_cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; - auto* is_ixex_opt = printer_cfg.option("is_ixex"); - if (!is_ixex_opt || !is_ixex_opt->value) + auto* is_imex_opt = printer_cfg.option("is_imex"); + if (!is_imex_opt || !is_imex_opt->value) return ""; // Per-plate mode takes priority over process preset. - std::string active_mode = get_ixex_mode(); + std::string active_mode = get_imex_mode(); if (active_mode == "primary") { const DynamicPrintConfig& process_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config; - auto* mode_opt = process_cfg.option("ixex_parallel_mode"); + auto* mode_opt = process_cfg.option("imex_parallel_mode"); if (mode_opt && !mode_opt->value.empty()) active_mode = mode_opt->value; } - auto* n_col_opt = printer_cfg.option("ixex_tools_per_gantry"); - auto* n_row_opt = printer_cfg.option("ixex_gantry_count"); - auto* cw_opt = printer_cfg.option("ixex_nozzle_clearance_x"); - auto* ch_opt = printer_cfg.option("ixex_nozzle_clearance_y"); - auto* mgn_opt = printer_cfg.option("ixex_carriage_margin"); + auto* n_col_opt = printer_cfg.option("imex_tools_per_gantry"); + auto* n_row_opt = printer_cfg.option("imex_gantry_count"); + auto* cw_opt = printer_cfg.option("imex_nozzle_clearance_x"); + auto* ch_opt = printer_cfg.option("imex_nozzle_clearance_y"); + auto* mgn_opt = printer_cfg.option("imex_carriage_margin"); return active_mode + "|" + std::to_string(n_col_opt ? n_col_opt->value : 2) + "x" + std::to_string(n_row_opt ? n_row_opt->value : 1) @@ -832,19 +832,19 @@ std::string PartPlate::build_ixex_cache_key() const // Ensure zone geometry (secondary boxes, collision strips, visual meshes) is up to date. // Called before any collision check AND before rendering so both paths share the same data. -void PartPlate::ensure_ixex_zones() +void PartPlate::ensure_imex_zones() { - std::string cache_key = build_ixex_cache_key(); - if (cache_key != m_ixex_zones_mode_cache) { - m_ixex_zones_mode_cache = cache_key; - calc_ixex_zones(); + std::string cache_key = build_imex_cache_key(); + if (cache_key != m_imex_zones_mode_cache) { + m_imex_zones_mode_cache = cache_key; + calc_imex_zones(); } } -bool PartPlate::has_ixex_placement_violations() +bool PartPlate::has_imex_placement_violations() { - ensure_ixex_zones(); - if (m_ixex_secondary_zone_boxes.empty() && m_ixex_collision_zones.empty()) + ensure_imex_zones(); + if (m_imex_secondary_zone_boxes.empty() && m_imex_collision_zones.empty()) return false; for (const auto& pr : obj_to_instance_set) { int obj_id = pr.first; @@ -855,11 +855,11 @@ bool PartPlate::has_ixex_placement_violations() Polygon hull = instance->convex_hull_2d(); if (hull.points.empty()) continue; - for (const auto& box : m_ixex_secondary_zone_boxes) { + for (const auto& box : m_imex_secondary_zone_boxes) { if (!intersection({box.polygon(true)}, {hull}).empty()) return true; } - for (const auto& strip : m_ixex_collision_zones) { + for (const auto& strip : m_imex_collision_zones) { if (!intersection({strip.polygon(true)}, {hull}).empty()) return true; } @@ -867,15 +867,15 @@ bool PartPlate::has_ixex_placement_violations() return false; } -void PartPlate::render_ixex_zones(bool force_default_color) +void PartPlate::render_imex_zones(bool force_default_color) { if (force_default_color) return; - ensure_ixex_zones(); + ensure_imex_zones(); // Read visualization theme from printer config. - struct IXexTheme { + struct IMEXTheme { ColorRGBA copy; // secondary copy zone fill ColorRGBA mirror; // secondary mirror zone fill ColorRGBA danger; // blocking collision strip @@ -883,7 +883,7 @@ void PartPlate::render_ixex_zones(bool force_default_color) }; // Standard (Okabe-Ito orange + sky blue) - static const IXexTheme k_standard = { + static const IMEXTheme k_standard = { { 0.337f, 0.706f, 0.914f, 0.45f }, // copy — sky blue #56B4E9 { 0.902f, 0.624f, 0.000f, 0.45f }, // mirror — orange #E69F00 { 0.850f, 0.100f, 0.100f, 0.55f }, // danger — red @@ -891,7 +891,7 @@ void PartPlate::render_ixex_zones(bool force_default_color) }; // Deuteranopia / Protanopia: avoids red-green confusion. // Danger strip uses strong blue-violet (red invisible to protanopes). - static const IXexTheme k_deuteranopia = { + static const IMEXTheme k_deuteranopia = { { 0.000f, 0.447f, 0.698f, 0.50f }, // copy — blue #0072B2 { 0.941f, 0.894f, 0.259f, 0.50f }, // mirror — yellow #F0E442 { 0.200f, 0.100f, 0.800f, 0.65f }, // danger — blue-violet (red not visible) @@ -899,24 +899,24 @@ void PartPlate::render_ixex_zones(bool force_default_color) }; // Tritanopia: avoids blue-yellow confusion. // Copy uses vermilion, mirror uses reddish-purple, margin uses teal. - static const IXexTheme k_tritanopia = { + static const IMEXTheme k_tritanopia = { { 0.835f, 0.369f, 0.000f, 0.50f }, // copy — vermilion #D55E00 { 0.800f, 0.475f, 0.655f, 0.50f }, // mirror — reddish purple #CC79A7 { 0.850f, 0.100f, 0.100f, 0.55f }, // danger — red (visible to tritanopes) { 0.000f, 0.700f, 0.600f, 0.45f }, // margin — teal }; // High contrast: saturated, higher alpha for low-vision users. - static const IXexTheme k_high_contrast = { + static const IMEXTheme k_high_contrast = { { 0.000f, 0.600f, 1.000f, 0.65f }, // copy — vivid blue { 1.000f, 0.600f, 0.000f, 0.65f }, // mirror — vivid orange { 1.000f, 0.000f, 0.000f, 0.75f }, // danger — full red { 0.000f, 1.000f, 0.200f, 0.60f }, // margin — bright green }; - const IXexTheme* theme = &k_standard; + const IMEXTheme* theme = &k_standard; if (wxGetApp().preset_bundle) { const DynamicPrintConfig& pcfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; - if (auto* t = pcfg.option("ixex_viz_theme")) { + if (auto* t = pcfg.option("imex_viz_theme")) { if (t->value == "deuteranopia") theme = &k_deuteranopia; else if (t->value == "tritanopia") theme = &k_tritanopia; else if (t->value == "high_contrast") theme = &k_high_contrast; @@ -926,27 +926,27 @@ void PartPlate::render_ixex_zones(bool force_default_color) // Both fills and border lines use the flat shader already active from render(). glsafe(::glDepthMask(GL_FALSE)); - if (!m_ixex_copy_zones.empty()) - for (GLModel& z : m_ixex_copy_zones) + if (!m_imex_copy_zones.empty()) + for (GLModel& z : m_imex_copy_zones) if (z.is_initialized()) { z.set_color(theme->copy); z.render(); } - if (!m_ixex_mirror_zones.empty()) - for (GLModel& z : m_ixex_mirror_zones) + if (!m_imex_mirror_zones.empty()) + for (GLModel& z : m_imex_mirror_zones) if (z.is_initialized()) { z.set_color(theme->mirror); z.render(); } glsafe(::glDepthMask(GL_TRUE)); - if (!m_ixex_collision_overlay.empty()) { + if (!m_imex_collision_overlay.empty()) { glsafe(::glDepthMask(GL_FALSE)); - for (GLModel& s : m_ixex_collision_overlay) + for (GLModel& s : m_imex_collision_overlay) if (s.is_initialized()) { s.set_color(theme->danger); s.render(); } glsafe(::glDepthMask(GL_TRUE)); } - if (!m_ixex_margin_overlay.empty()) { + if (!m_imex_margin_overlay.empty()) { glsafe(::glDepthMask(GL_FALSE)); - for (GLModel& b : m_ixex_margin_overlay) + for (GLModel& b : m_imex_margin_overlay) if (b.is_initialized()) { b.set_color(theme->margin); b.render(); } glsafe(::glDepthMask(GL_TRUE)); } @@ -1683,17 +1683,17 @@ void PartPlate::render_icons(bool bottom, bool only_name, int hover_id) } else render_icon_texture(m_move_front_icon.model, m_partplate_list->m_move_front_texture); - // iXex mode icon — only when is_ixex is active + // IDEX/IQEX mode icon — only when is_imex is active { PresetBundle* pb = wxGetApp().preset_bundle; - auto* is_ixex_opt = pb ? pb->printers.get_edited_preset().config.option("is_ixex") : nullptr; - if (is_ixex_opt && is_ixex_opt->value) { - if (hover_id == (int)PLATE_IXEX_MODE_ID) { - render_icon_texture(m_ixex_mode_icon.model, m_partplate_list->m_ixex_mode_hovered_texture); - std::string cur = get_ixex_mode(); - show_tooltip(_u8L("iXex mode: ") + cur + _u8L(" (left-click to cycle, right-click for menu)")); + auto* is_imex_opt = pb ? pb->printers.get_edited_preset().config.option("is_imex") : nullptr; + if (is_imex_opt && is_imex_opt->value) { + if (hover_id == (int)PLATE_IMEX_MODE_ID) { + render_icon_texture(m_imex_mode_icon.model, m_partplate_list->m_imex_mode_hovered_texture); + std::string cur = get_imex_mode(); + show_tooltip(_u8L("IDEX/IQEX mode: ") + cur + _u8L(" (left-click to cycle, right-click for menu)")); } else { - render_icon_texture(m_ixex_mode_icon.model, m_partplate_list->m_ixex_mode_texture); + render_icon_texture(m_imex_mode_icon.model, m_partplate_list->m_imex_mode_texture); } } } @@ -2007,11 +2007,11 @@ void PartPlate::register_raycasters_for_picking(GLCanvas3D &canvas) if (dual_bbl) register_model_for_picking(canvas, m_plate_filament_map_icon, picking_id_component(PLATE_FILAMENT_MAP_ID)); - // Register iXex mode icon only when iXex is active on the current printer preset. + // Register IDEX/IQEX mode icon only when IDEX/IQEX is active on the current printer preset. if (preset) { - auto* is_ixex_opt = preset->printers.get_edited_preset().config.option("is_ixex"); - if (is_ixex_opt && is_ixex_opt->value) - register_model_for_picking(canvas, m_ixex_mode_icon, picking_id_component(PLATE_IXEX_MODE_ID)); + auto* is_imex_opt = preset->printers.get_edited_preset().config.option("is_imex"); + if (is_imex_opt && is_imex_opt->value) + register_model_for_picking(canvas, m_imex_mode_icon, picking_id_component(PLATE_IMEX_MODE_ID)); } } @@ -3024,8 +3024,8 @@ bool PartPlate::contain_instance_totally(int obj_id, int instance_id) const //check whether instance is outside the plate or not bool PartPlate::check_outside(int obj_id, int instance_id, BoundingBoxf3* bounding_box) { - // Ensure iXex zone geometry is current before any placement check. - ensure_ixex_zones(); + // Ensure IDEX/IQEX zone geometry is current before any placement check. + ensure_imex_zones(); bool outside = true; @@ -3070,14 +3070,14 @@ bool PartPlate::check_outside(int obj_id, int instance_id, BoundingBoxf3* boundi outside = false; } - // iXex placement check (prepare-mode bounding-box test). + // IDEX/IQEX placement check (prepare-mode bounding-box test). // Block objects that overlap secondary (copy/mirror) zones or the carriage // danger strip at the primary zone boundary. Reuses the existing // outside=true → instance_outside_set → update_states() → blocks slicing path. - if (!outside && (!m_ixex_secondary_zone_boxes.empty() || !m_ixex_collision_zones.empty())) { + if (!outside && (!m_imex_secondary_zone_boxes.empty() || !m_imex_collision_zones.empty())) { Polygon obj_hull = instance->convex_hull_2d(); // scaled Clipper coords // 1. Object must not touch any secondary zone. - for (const auto& box : m_ixex_secondary_zone_boxes) { + for (const auto& box : m_imex_secondary_zone_boxes) { Polygon p = box.polygon(true); if (!intersection({ p }, { obj_hull }).empty()) { outside = true; @@ -3086,7 +3086,7 @@ bool PartPlate::check_outside(int obj_id, int instance_id, BoundingBoxf3* boundi } // 2. Object must not enter the carriage danger strip inside the primary zone. if (!outside) { - for (const auto& strip : m_ixex_collision_zones) { + for (const auto& strip : m_imex_collision_zones) { Polygon strip_poly = strip.polygon(true); if (!intersection({ strip_poly }, { obj_hull }).empty()) { outside = true; @@ -3684,8 +3684,8 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, co const BoundingBox& pp_bbox = poly.contour.bounding_box(); calc_gridlines(poly, pp_bbox); - m_ixex_zones_mode_cache = "\x01"; // force rebuild on next render - calc_ixex_zones(); + m_imex_zones_mode_cache = "\x01"; // force rebuild on next render + calc_imex_zones(); calc_vertex_for_icons(0, m_del_icon); calc_vertex_for_icons(1, m_orient_icon); @@ -3699,9 +3699,9 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, co calc_vertex_for_icons(dual_bbl ? 5 : 6, m_plate_filament_map_icon); calc_vertex_for_icons(dual_bbl ? 6 : 5, m_move_front_icon); { - auto* is_ixex_opt = preset->printers.get_edited_preset().config.option("is_ixex"); - if (is_ixex_opt && is_ixex_opt->value) - calc_vertex_for_icons(dual_bbl ? 7 : 6, m_ixex_mode_icon); + auto* is_imex_opt = preset->printers.get_edited_preset().config.option("is_imex"); + if (is_imex_opt && is_imex_opt->value) + calc_vertex_for_icons(dual_bbl ? 7 : 6, m_imex_mode_icon); } calc_vertex_for_number(0, false, m_plate_idx_icon); @@ -3795,7 +3795,7 @@ void PartPlate::render(const Transform3d& view_matrix, const Transform3d& projec render_background(force_background_color); render_exclude_area(force_background_color); - render_ixex_zones(force_background_color); + render_imex_zones(force_background_color); if(m_selected && wxGetApp().plater()->get_enable_wrapping_detection()){ if(!m_wrapping_detection_triangles.is_initialized()){ auto points = get_plate_wrapping_detection_area(); @@ -4572,17 +4572,17 @@ void PartPlateList::generate_icon_textures() } } - // iXex mode icon textures (fall back gracefully if SVG not present yet) + // IDEX/IQEX mode icon textures (fall back gracefully if SVG not present yet) { - file_name = path + (m_is_dark ? "plate_ixex_mode_dark.svg" : "plate_ixex_mode.svg"); - if (!m_ixex_mode_texture.load_from_svg_file(file_name, true, false, false, icon_size)) { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":load file %1% failed (iXex mode icon)") % file_name; + file_name = path + (m_is_dark ? "plate_imex_mode_dark.svg" : "plate_imex_mode.svg"); + if (!m_imex_mode_texture.load_from_svg_file(file_name, true, false, false, icon_size)) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":load file %1% failed (IDEX/IQEX mode icon)") % file_name; } } { - file_name = path + (m_is_dark ? "plate_ixex_mode_hover_dark.svg" : "plate_ixex_mode_hover.svg"); - if (!m_ixex_mode_hovered_texture.load_from_svg_file(file_name, true, false, false, icon_size)) { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":load file %1% failed (iXex mode hover icon)") % file_name; + file_name = path + (m_is_dark ? "plate_imex_mode_hover_dark.svg" : "plate_imex_mode_hover.svg"); + if (!m_imex_mode_hovered_texture.load_from_svg_file(file_name, true, false, false, icon_size)) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":load file %1% failed (IDEX/IQEX mode hover icon)") % file_name; } } @@ -4629,8 +4629,8 @@ void PartPlateList::release_icon_textures() m_plate_set_filament_map_hovered_texture.reset(); m_plate_name_edit_texture.reset(); m_plate_name_edit_hovered_texture.reset(); - m_ixex_mode_texture.reset(); - m_ixex_mode_hovered_texture.reset(); + m_imex_mode_texture.reset(); + m_imex_mode_hovered_texture.reset(); for (int i = 0;i < MAX_PLATE_COUNT; i++) { m_idx_textures[i].reset(); } diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 773524c77c..423de28585 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -136,14 +136,14 @@ private: GLModel m_logo_triangles; GLModel m_gridlines; GLModel m_gridlines_bolder; - std::vector m_ixex_copy_zones; // blue tint (Wong #56B4E9) - std::vector m_ixex_mirror_zones; // orange tint (Wong #E69F00) - std::vector m_ixex_secondary_zone_boxes; // secondary (copy/mirror) zone rects — objects blocked here - std::vector m_ixex_collision_zones; // carriage danger strips inside primary zone (mm) - std::vector m_ixex_collision_overlay; // red-orange rendered fill for danger strips - std::vector m_ixex_margin_overlay; // amber advisory bands just inside collision strips - std::optional 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 + std::vector m_imex_copy_zones; // blue tint (Wong #56B4E9) + std::vector m_imex_mirror_zones; // orange tint (Wong #E69F00) + std::vector m_imex_secondary_zone_boxes; // secondary (copy/mirror) zone rects — objects blocked here + std::vector m_imex_collision_zones; // carriage danger strips inside primary zone (mm) + std::vector m_imex_collision_overlay; // red-orange rendered fill for danger strips + std::vector m_imex_margin_overlay; // amber advisory bands just inside collision strips + std::optional m_imex_primary_zone_box; // primary zone extents in mm; empty when IDEX/IQEX is off/primary-only + std::string m_imex_zones_mode_cache{ "\x01" }; // cached mode+topology key; sentinel = unbuilt GLModel m_height_limit_common; GLModel m_height_limit_bottom; GLModel m_height_limit_top; @@ -155,7 +155,7 @@ private: PickingModel m_plate_filament_map_icon; PickingModel m_plate_name_edit_icon; PickingModel m_move_front_icon; - PickingModel m_ixex_mode_icon; + PickingModel m_imex_mode_icon; GLModel m_plate_idx_icon; GLTexture m_texture; @@ -187,10 +187,10 @@ private: void calc_triangles_from_polygon(const ExPolygon &poly, GLModel& render_model); void calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox); void calc_height_limit(); - void calc_ixex_zones(); - void ensure_ixex_zones(); - std::string build_ixex_cache_key() const; - void render_ixex_zones(bool force_default_color); + void calc_imex_zones(); + void ensure_imex_zones(); + std::string build_imex_cache_key() const; + void render_imex_zones(bool force_default_color); void calc_vertex_for_number(int index, bool one_number, GLModel &buffer); void calc_vertex_for_plate_name_edit_icon(GLTexture *texture, int index, PickingModel &model); void calc_vertex_for_icons(int index, PickingModel &model); @@ -222,7 +222,7 @@ private: public: static constexpr unsigned int PLATE_NAME_HOVER_ID = 6; static constexpr unsigned int PLATE_FILAMENT_MAP_ID = 8; - static constexpr unsigned int PLATE_IXEX_MODE_ID = 9; + static constexpr unsigned int PLATE_IMEX_MODE_ID = 9; static constexpr unsigned int GRABBER_COUNT = 10; static ColorRGBA SELECT_COLOR; @@ -283,9 +283,9 @@ public: bool get_spiral_vase_mode() const; void set_spiral_vase_mode(bool spiral_mode, bool as_global); - std::string get_ixex_mode() const; - void set_ixex_mode(const std::string& mode); - void reset_ixex_mode(); + std::string get_imex_mode() const; + void set_imex_mode(const std::string& mode); + void reset_imex_mode(); std::vector get_plate_wrapping_detection_area() const; @@ -451,14 +451,14 @@ public: { return m_ready_for_slice && !m_apply_invalid; } - // 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 ixex_primary_zone() { ensure_ixex_zones(); return m_ixex_primary_zone_box; } - // Returns carriage collision strips (mm) for the current iXex mode. - // Always call ixex_primary_zone() first to ensure the cache is warm. - const std::vector& ixex_collision_zones() const { return m_ixex_collision_zones; } + // Returns true if any instance on this plate overlaps an IDEX/IQEX secondary or collision zone. + bool has_imex_placement_violations(); + // Returns the primary-zone bounding box in mm when an IDEX/IQEX parallel mode is active. + // Empty (nullopt) when IDEX/IQEX is off or the mode is "primary" (full-bed). + std::optional imex_primary_zone() { ensure_imex_zones(); return m_imex_primary_zone_box; } + // Returns carriage collision strips (mm) for the current IDEX/IQEX mode. + // Always call imex_primary_zone() first to ensure the cache is warm. + const std::vector& imex_collision_zones() const { return m_imex_collision_zones; } void update_slice_ready_status(bool ready_slice) { m_ready_for_slice = ready_slice; @@ -634,8 +634,8 @@ class PartPlateList : public ObjectBase GLTexture m_plate_set_filament_map_hovered_texture; GLTexture m_plate_name_edit_texture; GLTexture m_plate_name_edit_hovered_texture; - GLTexture m_ixex_mode_texture; - GLTexture m_ixex_mode_hovered_texture; + GLTexture m_imex_mode_texture; + GLTexture m_imex_mode_hovered_texture; GLTexture m_idx_textures[MAX_PLATE_COUNT]; // set render option bool render_bedtype_logo = true; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5c85f75f45..6e5753c546 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -7722,13 +7722,13 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool q->post_process_string_object_exception(err); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warning=%2%")%err.string%warning.string; - // iXex placement check: if objects overlap secondary zones, treat it as a + // IDEX/IQEX placement check: if objects overlap secondary zones, treat it as a // validation error so the standard pathway handles button state, notifications, // and auto-slice blocking consistently. if (err.string.empty()) { - PartPlate* ixex_plate = partplate_list.get_curr_plate(); - if (ixex_plate && ixex_plate->has_ixex_placement_violations()) - err.string = _u8L("Cannot slice: objects are in secondary zones reserved for iXex parallel printing."); + PartPlate* imex_plate = partplate_list.get_curr_plate(); + if (imex_plate && imex_plate->has_imex_placement_violations()) + err.string = _u8L("Cannot slice: objects are in secondary zones reserved for IDEX/IQEX parallel printing."); } if (err.string.empty()) { @@ -17640,7 +17640,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi update(); p->partplate_list.select_plate(0); } - else if (action == (int)PartPlate::PLATE_IXEX_MODE_ID) + else if (action == (int)PartPlate::PLATE_IMEX_MODE_ID) { ret = select_plate(plate_index); if (!ret) { @@ -17649,7 +17649,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi std::vector modes; modes.push_back("primary"); const DynamicPrintConfig& printer_cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; - auto* names_opt = printer_cfg.option("ixex_mode_names"); + auto* names_opt = printer_cfg.option("imex_mode_names"); if (names_opt) { for (const auto& n : names_opt->values) if (!n.empty()) modes.push_back(n); @@ -17658,7 +17658,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi if (right_click) { // Show a popup menu with all modes. wxMenu menu; - std::string current = curr_plate->get_ixex_mode(); + std::string current = curr_plate->get_imex_mode(); for (size_t i = 0; i < modes.size(); ++i) { wxMenuItem* item = menu.AppendRadioItem(wxID_HIGHEST + (int)i, from_u8(modes[i])); if (modes[i] == current) @@ -17667,8 +17667,8 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi menu.Bind(wxEVT_MENU, [this, curr_plate, &modes](wxCommandEvent& e) { int idx = e.GetId() - wxID_HIGHEST; if (idx >= 0 && idx < (int)modes.size()) { - take_snapshot("set ixex mode"); - curr_plate->set_ixex_mode(modes[idx]); + take_snapshot("set imex mode"); + curr_plate->set_imex_mode(modes[idx]); update_project_dirty_from_presets(); set_plater_dirty(true); update(); @@ -17678,13 +17678,13 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi ret = 1; // signal to caller: popup was shown, suppress plate context menu } else { // Left-click: cycle to next mode. - std::string current = curr_plate->get_ixex_mode(); + std::string current = curr_plate->get_imex_mode(); auto it = std::find(modes.begin(), modes.end(), current); size_t next_idx = (it == modes.end()) ? 0 : ((it - modes.begin() + 1) % modes.size()); std::string next_mode = modes[next_idx]; if (next_mode != current) { - take_snapshot("set ixex mode"); - curr_plate->set_ixex_mode(next_mode); + take_snapshot("set imex mode"); + curr_plate->set_imex_mode(next_mode); update_project_dirty_from_presets(); set_plater_dirty(true); update(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index a048597a4d..cbc95a328b 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -4338,7 +4338,7 @@ void TabPrinter::build() } // --------------------------------------------------------------------------- -// IXexModesCtrl — visual parallel-mode editor for the iXex printer tab +// IMEXModesCtrl — visual parallel-mode editor for the IDEX/IQEX printer tab // // Tool button states: // 0 = Inactive (grey) — not participating in this mode @@ -4348,7 +4348,7 @@ void TabPrinter::build() // // Active-tools string format: "idx:P,idx:C,idx:M" (backwards-compat: plain "idx" = Primary) // --------------------------------------------------------------------------- -class IXexModesCtrl : public wxPanel { +class IMEXModesCtrl : public wxPanel { public: std::function on_change; @@ -4360,7 +4360,7 @@ public: return 0; // "front-left" default } - IXexModesCtrl(wxWindow* parent, int n_cols, int n_rows, int layout = 0) + IMEXModesCtrl(wxWindow* parent, int n_cols, int n_rows, int layout = 0) : wxPanel(parent, wxID_ANY), m_n_cols(std::max(1, n_cols)), m_n_rows(std::max(1, n_rows)), m_layout(layout) { m_outer = new wxBoxSizer(wxVERTICAL); @@ -4437,9 +4437,9 @@ public: void load_from_config(const DynamicPrintConfig& cfg) { clear_rows(); - auto* names = cfg.option("ixex_mode_names"); - auto* tools = cfg.option("ixex_mode_active_tools"); - auto* gcodes = cfg.option("ixex_mode_gcodes"); + auto* names = cfg.option("imex_mode_names"); + auto* tools = cfg.option("imex_mode_active_tools"); + auto* gcodes = cfg.option("imex_mode_gcodes"); size_t n = names ? names->values.size() : 0; for (size_t i = 0; i < n; ++i) add_row(names->values[i], @@ -4931,14 +4931,14 @@ void TabPrinter::build_fff() option.opt.height = gcode_field_height;//150; optgroup->append_single_option_line(option, "printer_machine_gcode#template-custom-g-code"); - page = add_options_page(L("iXex"), "custom-gcode_multi_material"); // ORCA: icon only visible on placeholders + page = add_options_page(L("IDEX/IQEX"), "custom-gcode_multi_material"); // ORCA: icon only visible on placeholders optgroup = page->new_optgroup(L("Carriage Configuration"), L"param_advanced"); - optgroup->append_single_option_line("is_ixex"); - optgroup->append_single_option_line("ixex_gantry_count"); - optgroup->append_single_option_line("ixex_tools_per_gantry"); + optgroup->append_single_option_line("is_imex"); + optgroup->append_single_option_line("imex_gantry_count"); + optgroup->append_single_option_line("imex_tools_per_gantry"); { // Tool 0 corner selector - auto opt = optgroup->get_option("ixex_tool_layout"); + auto opt = optgroup->get_option("imex_tool_layout"); auto line = Line{ opt.opt.label, opt.opt.tooltip }; line.append_option(opt); line.widget = [this](wxWindow* parent) -> wxSizer* { @@ -4947,37 +4947,37 @@ void TabPrinter::build_fff() _L("Rear-left"), _L("Rear-right") }; static const char* values[] = { "front-left", "front-right", "rear-left", "rear-right" }; - m_ixex_layout_combo = new ComboBox(parent, wxID_ANY, wxEmptyString, + m_imex_layout_combo = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(12 * wxGetApp().em_unit(), -1), 4, choices, wxCB_READONLY); - m_ixex_layout_combo->GetDropDown().SetUseContentWidth(true); + m_imex_layout_combo->GetDropDown().SetUseContentWidth(true); // Set current selection std::string cur = "front-left"; - if (auto* o = m_config->option("ixex_tool_layout")) cur = o->value; + if (auto* o = m_config->option("imex_tool_layout")) cur = o->value; for (int i = 0; i < 4; ++i) - if (cur == values[i]) { m_ixex_layout_combo->SetSelection(i); break; } - m_ixex_layout_combo->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { + if (cur == values[i]) { m_imex_layout_combo->SetSelection(i); break; } + m_imex_layout_combo->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { static const char* layout_vals[] = { "front-left", "front-right", "rear-left", "rear-right" }; - int sel = m_ixex_layout_combo->GetSelection(); + int sel = m_imex_layout_combo->GetSelection(); std::string val = (sel >= 0 && sel < 4) ? layout_vals[sel] : "front-left"; - m_config->set_key_value("ixex_tool_layout", new ConfigOptionString(val)); - on_value_change("ixex_tool_layout", val); - if (m_ixex_modes_ctrl) - m_ixex_modes_ctrl->set_grid_size( - m_config->opt_int("ixex_tools_per_gantry"), - m_config->opt_int("ixex_gantry_count"), - IXexModesCtrl::parse_layout(val)); + m_config->set_key_value("imex_tool_layout", new ConfigOptionString(val)); + on_value_change("imex_tool_layout", val); + if (m_imex_modes_ctrl) + m_imex_modes_ctrl->set_grid_size( + m_config->opt_int("imex_tools_per_gantry"), + m_config->opt_int("imex_gantry_count"), + IMEXModesCtrl::parse_layout(val)); }); auto* s = new wxBoxSizer(wxHORIZONTAL); - s->Add(m_ixex_layout_combo, 0, wxALIGN_CENTER_VERTICAL); + s->Add(m_imex_layout_combo, 0, wxALIGN_CENTER_VERTICAL); return s; }; optgroup->append_line(line); } - optgroup->append_single_option_line("ixex_nozzle_clearance_x"); - optgroup->append_single_option_line("ixex_nozzle_clearance_y"); - optgroup->append_single_option_line("ixex_carriage_margin"); + optgroup->append_single_option_line("imex_nozzle_clearance_x"); + optgroup->append_single_option_line("imex_nozzle_clearance_y"); + optgroup->append_single_option_line("imex_carriage_margin"); { static const wxString theme_choices[] = { @@ -4986,27 +4986,27 @@ void TabPrinter::build_fff() _L("Tritanopia (blue-yellow)"), _L("High Contrast") }; static const char* theme_vals[] = { "standard", "deuteranopia", "tritanopia", "high_contrast" }; - auto opt = optgroup->get_option("ixex_viz_theme"); + auto opt = optgroup->get_option("imex_viz_theme"); auto line = Line{ opt.opt.label, opt.opt.tooltip }; line.append_option(opt); line.widget = [this](wxWindow* parent) -> wxSizer* { - m_ixex_theme_combo = new ComboBox(parent, wxID_ANY, wxEmptyString, + m_imex_theme_combo = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(22 * wxGetApp().em_unit(), -1), 4, theme_choices, wxCB_READONLY); - m_ixex_theme_combo->GetDropDown().SetUseContentWidth(true); + m_imex_theme_combo->GetDropDown().SetUseContentWidth(true); std::string cur = "standard"; - if (auto* o = m_config->option("ixex_viz_theme")) cur = o->value; + if (auto* o = m_config->option("imex_viz_theme")) cur = o->value; for (int i = 0; i < 4; ++i) - if (cur == theme_vals[i]) { m_ixex_theme_combo->SetSelection(i); break; } - m_ixex_theme_combo->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { - int sel = m_ixex_theme_combo->GetSelection(); + if (cur == theme_vals[i]) { m_imex_theme_combo->SetSelection(i); break; } + m_imex_theme_combo->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent&) { + int sel = m_imex_theme_combo->GetSelection(); std::string val = (sel >= 0 && sel < 4) ? theme_vals[sel] : "standard"; - m_config->set_key_value("ixex_viz_theme", new ConfigOptionString(val)); - on_value_change("ixex_viz_theme", val); + m_config->set_key_value("imex_viz_theme", new ConfigOptionString(val)); + on_value_change("imex_viz_theme", val); }); auto* s = new wxBoxSizer(wxHORIZONTAL); - s->Add(m_ixex_theme_combo, 0, wxALIGN_CENTER_VERTICAL); + s->Add(m_imex_theme_combo, 0, wxALIGN_CENTER_VERTICAL); return s; }; optgroup->append_line(line); @@ -5018,23 +5018,23 @@ void TabPrinter::build_fff() auto line = Line{ L("Modes"), L("") }; line.full_width = 1; line.widget = [this](wxWindow* parent) -> wxSizer* { - int n_cols = m_config->opt_int("ixex_tools_per_gantry"); - int n_rows = m_config->opt_int("ixex_gantry_count"); + int n_cols = m_config->opt_int("imex_tools_per_gantry"); + int n_rows = m_config->opt_int("imex_gantry_count"); std::string layout_str = "front-left"; - if (auto* o = m_config->option("ixex_tool_layout")) layout_str = o->value; - int layout = IXexModesCtrl::parse_layout(layout_str); - m_ixex_modes_ctrl = new IXexModesCtrl(parent, n_cols, n_rows, layout); - m_ixex_modes_ctrl->load_from_config(*m_config); - m_ixex_modes_ctrl->on_change = [this]() { - auto [names, tools, gcodes] = m_ixex_modes_ctrl->get_mode_data(); - m_config->set_key_value("ixex_mode_names", new ConfigOptionStrings(names)); - m_config->set_key_value("ixex_mode_active_tools", new ConfigOptionStrings(tools)); - m_config->set_key_value("ixex_mode_gcodes", new ConfigOptionStrings(gcodes)); + if (auto* o = m_config->option("imex_tool_layout")) layout_str = o->value; + int layout = IMEXModesCtrl::parse_layout(layout_str); + m_imex_modes_ctrl = new IMEXModesCtrl(parent, n_cols, n_rows, layout); + m_imex_modes_ctrl->load_from_config(*m_config); + m_imex_modes_ctrl->on_change = [this]() { + auto [names, tools, gcodes] = m_imex_modes_ctrl->get_mode_data(); + m_config->set_key_value("imex_mode_names", new ConfigOptionStrings(names)); + m_config->set_key_value("imex_mode_active_tools", new ConfigOptionStrings(tools)); + m_config->set_key_value("imex_mode_gcodes", new ConfigOptionStrings(gcodes)); update_dirty(); - on_value_change("ixex_mode_names", std::string("")); + on_value_change("imex_mode_names", std::string("")); }; auto* sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(m_ixex_modes_ctrl, 1, wxEXPAND); + sizer->Add(m_imex_modes_ctrl, 1, wxEXPAND); return sizer; }; modes_og->append_line(line); @@ -5622,28 +5622,28 @@ void TabPrinter::reload_config() if (m_config) { // Sync layout combo - if (m_ixex_layout_combo) { + if (m_imex_layout_combo) { static const char* layout_vals[] = { "front-left", "front-right", "rear-left", "rear-right" }; std::string cur = "front-left"; - if (auto* o = m_config->option("ixex_tool_layout")) cur = o->value; + if (auto* o = m_config->option("imex_tool_layout")) cur = o->value; for (int i = 0; i < 4; ++i) - if (cur == layout_vals[i]) { m_ixex_layout_combo->SetSelection(i); break; } + if (cur == layout_vals[i]) { m_imex_layout_combo->SetSelection(i); break; } } // Sync theme combo - if (m_ixex_theme_combo) { + if (m_imex_theme_combo) { static const char* theme_vals[] = { "standard", "deuteranopia", "tritanopia", "high_contrast" }; std::string cur = "standard"; - if (auto* o = m_config->option("ixex_viz_theme")) cur = o->value; + if (auto* o = m_config->option("imex_viz_theme")) cur = o->value; for (int i = 0; i < 4; ++i) - if (cur == theme_vals[i]) { m_ixex_theme_combo->SetSelection(i); break; } + if (cur == theme_vals[i]) { m_imex_theme_combo->SetSelection(i); break; } } - if (m_ixex_modes_ctrl) { - int n_cols = m_config->opt_int("ixex_tools_per_gantry"); - int n_rows = m_config->opt_int("ixex_gantry_count"); + if (m_imex_modes_ctrl) { + int n_cols = m_config->opt_int("imex_tools_per_gantry"); + int n_rows = m_config->opt_int("imex_gantry_count"); std::string layout_str = "front-left"; - if (auto* o = m_config->option("ixex_tool_layout")) layout_str = o->value; - m_ixex_modes_ctrl->set_grid_size(n_cols, n_rows, IXexModesCtrl::parse_layout(layout_str)); - m_ixex_modes_ctrl->load_from_config(*m_config); + if (auto* o = m_config->option("imex_tool_layout")) layout_str = o->value; + m_imex_modes_ctrl->set_grid_size(n_cols, n_rows, IMEXModesCtrl::parse_layout(layout_str)); + m_imex_modes_ctrl->load_from_config(*m_config); } } } @@ -5662,9 +5662,9 @@ void TabPrinter::clear_pages() { Tab::clear_pages(); m_reset_to_filament_color = nullptr; - m_ixex_modes_ctrl = nullptr; - m_ixex_layout_combo = nullptr; - m_ixex_theme_combo = nullptr; + m_imex_modes_ctrl = nullptr; + m_imex_layout_combo = nullptr; + m_imex_theme_combo = nullptr; } void TabPrinter::toggle_options() @@ -5874,13 +5874,13 @@ void TabPrinter::update_fff() m_use_silent_mode = m_config->opt_bool("silent_mode"); } - // Sync iXex tool grid whenever carriage configuration changes. + // Sync IDEX/IQEX tool grid whenever carriage configuration changes. // set_grid_size() is a no-op when dimensions and layout are unchanged. - if (m_ixex_modes_ctrl) { - int n_cols = m_config->opt_int("ixex_tools_per_gantry"); - int n_rows = m_config->opt_int("ixex_gantry_count"); - std::string layout_str = m_config->opt_string("ixex_tool_layout"); - m_ixex_modes_ctrl->set_grid_size(n_cols, n_rows, IXexModesCtrl::parse_layout(layout_str)); + if (m_imex_modes_ctrl) { + int n_cols = m_config->opt_int("imex_tools_per_gantry"); + int n_rows = m_config->opt_int("imex_gantry_count"); + std::string layout_str = m_config->opt_string("imex_tool_layout"); + m_imex_modes_ctrl->set_grid_size(n_cols, n_rows, IMEXModesCtrl::parse_layout(layout_str)); } toggle_options(); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 7d86278db7..c76f6b5f0d 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -589,7 +589,7 @@ public: void set_custom_gcode(const t_config_option_key& opt_key, const std::string& value) override; }; -class IXexModesCtrl; +class IMEXModesCtrl; class TabPrinter : public Tab { @@ -605,9 +605,9 @@ private: std::vector m_pages_sla; wxBoxSizer* m_presets_sizer {nullptr}; - IXexModesCtrl* m_ixex_modes_ctrl {nullptr}; - ComboBox* m_ixex_layout_combo {nullptr}; - ComboBox* m_ixex_theme_combo {nullptr}; + IMEXModesCtrl* m_imex_modes_ctrl {nullptr}; + ComboBox* m_imex_layout_combo {nullptr}; + ComboBox* m_imex_theme_combo {nullptr}; public: ScalableButton* m_reset_to_filament_color = nullptr;