diff --git a/src/slic3r/GUI/BulkExportDialog.cpp b/src/slic3r/GUI/BulkExportDialog.cpp index b6d16fd6b0..e6a61a614b 100644 --- a/src/slic3r/GUI/BulkExportDialog.cpp +++ b/src/slic3r/GUI/BulkExportDialog.cpp @@ -41,9 +41,9 @@ void BulkExportDialog::Item::init_input_name_ctrl(wxBoxSizer* row_sizer, const s row_sizer->Add(m_text_ctrl, 1, wxEXPAND, BORDER_W); } -void BulkExportDialog::Item::init_selection_ctrl(wxBoxSizer* row_sizer, int id) +void BulkExportDialog::Item::init_selection_ctrl(wxBoxSizer* row_sizer, int bed_index) { - m_checkbox = new ::CheckBox(m_parent, std::to_string(id)); + m_checkbox = new ::CheckBox(m_parent, std::to_string(bed_index + 1)); m_checkbox->SetFont(wxGetApp().bold_font()); wxGetApp().UpdateDarkUI(m_checkbox); m_checkbox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { @@ -58,17 +58,18 @@ BulkExportDialog::Item::Item( wxWindow *parent, wxBoxSizer *sizer, const fs::path &path, - Validator validator, - int id + const int bed_index, + Validator validator ): path(path), + bed_index(bed_index), m_parent(parent), m_valid_bmp(new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle("tick_mark"))), m_validator(std::move(validator)), m_directory(path.parent_path()) { wxBoxSizer* row_sizer = new wxBoxSizer(wxHORIZONTAL); - init_selection_ctrl(row_sizer, id); + init_selection_ctrl(row_sizer, bed_index); init_input_name_ctrl(row_sizer, path.filename().string()); row_sizer->Add(m_valid_bmp, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, BORDER_W); @@ -193,7 +194,7 @@ void BulkExportDialog::Item::update_valid_bmp() m_valid_bmp->SetBitmap(*get_bmp_bundle(get_bmp_name(m_status))); } -BulkExportDialog::BulkExportDialog(const std::vector &paths): +BulkExportDialog::BulkExportDialog(const std::vector> &paths): DPIDialog( nullptr, wxID_ANY, @@ -213,9 +214,8 @@ BulkExportDialog::BulkExportDialog(const std::vector &paths): m_sizer = new wxBoxSizer(wxVERTICAL); - int id{ 0 }; - for (const fs::path& path : paths) { - AddItem(path, ++id); + for (const auto&[bed_index, path] : paths) { + AddItem(path, bed_index); } // Add dialog's buttons @@ -237,9 +237,9 @@ BulkExportDialog::BulkExportDialog(const std::vector &paths): #endif } -void BulkExportDialog::AddItem(const fs::path& path, int id) +void BulkExportDialog::AddItem(const fs::path& path, int bed_index) { - m_items.push_back(std::make_unique(this, m_sizer, path, PathValidator{m_items}, id)); + m_items.push_back(std::make_unique(this, m_sizer, path, bed_index, PathValidator{m_items})); } bool BulkExportDialog::enable_ok_btn() const @@ -259,17 +259,17 @@ bool BulkExportDialog::Layout() return ret; } -std::vector> BulkExportDialog::get_paths() const { - std::vector> result; +std::vector>> BulkExportDialog::get_paths() const { + std::vector>> result; std::transform( m_items.begin(), m_items.end(), std::back_inserter(result), - [](const auto &item) -> std::optional { + [](const auto &item) -> std::pair> { if (!item->selected) { - return std::nullopt; + return {item->bed_index, std::nullopt}; } - return item->path; + return {item->bed_index, item->path}; } ); return result; diff --git a/src/slic3r/GUI/BulkExportDialog.hpp b/src/slic3r/GUI/BulkExportDialog.hpp index fc07c07f9b..deff9b2b08 100644 --- a/src/slic3r/GUI/BulkExportDialog.hpp +++ b/src/slic3r/GUI/BulkExportDialog.hpp @@ -41,8 +41,8 @@ public: wxWindow *parent, wxBoxSizer *sizer, const boost::filesystem::path &path, - Validator validator, - int id + const int bed_index, + Validator validator ); Item(const Item &) = delete; Item& operator=(const Item &) = delete; @@ -56,6 +56,7 @@ public: bool is_valid() const { return m_status != ItemStatus::NoValid; } boost::filesystem::path path; + int bed_index{}; bool selected{true}; private: @@ -68,7 +69,7 @@ public: boost::filesystem::path m_directory{}; void init_input_name_ctrl(wxBoxSizer *row_sizer, const std::string &path); - void init_selection_ctrl(wxBoxSizer *row_sizer, int id); + void init_selection_ctrl(wxBoxSizer *row_sizer, int bed_index); void update(); }; @@ -78,16 +79,17 @@ private: wxBoxSizer *m_sizer{nullptr}; public: - BulkExportDialog(const std::vector &paths); + + BulkExportDialog(const std::vector> &paths); bool Layout() override; - std::vector> get_paths() const; + std::vector>> get_paths() const; protected: void on_dpi_changed(const wxRect &) override; void on_sys_color_changed() override {} private: - void AddItem(const boost::filesystem::path &path, int id); + void AddItem(const boost::filesystem::path &path, int bed_index); bool enable_ok_btn() const; }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e0efd941e4..8530e538a9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6035,8 +6035,7 @@ void Plater::export_gcode_to_path( struct PrintToExport { std::reference_wrapper print; std::reference_wrapper processor_result; - boost::filesystem::path output_path; - std::size_t bed{}; + int bed{}; }; void Plater::with_mocked_fff_background_process( @@ -6079,13 +6078,12 @@ void Plater::export_all_gcodes(bool prefer_removable) { const fs_path &output_dir{*optional_output_dir}; - std::vector prints_to_export; - std::vector paths; - - for (std::size_t print_index{0}; print_index < this->get_fff_prints().size(); ++print_index) { + std::map prints_to_export; + std::vector> paths; + for (int print_index{0}; print_index < this->get_fff_prints().size(); ++print_index) { const std::unique_ptr &print{this->get_fff_prints()[print_index]}; - if (!print || print->empty()) { + if (!print || !is_sliceable(s_print_statuses[print_index])) { continue; } @@ -6111,28 +6109,27 @@ void Plater::export_all_gcodes(bool prefer_removable) { + default_filename.extension().string() }; const fs::path output_file{output_dir / filename}; - prints_to_export.push_back({*print, this->p->gcode_results[print_index], output_file, print_index}); - paths.push_back(output_file); + prints_to_export.insert({ + print_index, + {*print, this->p->gcode_results[print_index], print_index} + }); + paths.emplace_back(print_index, output_file); } BulkExportDialog dialog{paths}; if (dialog.ShowModal() != wxID_OK) { return; } - std::vector> output_paths{dialog.get_paths()}; - for (std::size_t path_index{0}; path_index < paths.size(); ++path_index) { - prints_to_export[path_index].output_path = paths[path_index]; - } + const std::vector>> output_paths{dialog.get_paths()}; bool path_on_removable_media{false}; - - - for (std::size_t path_index{0}; path_index < paths.size(); ++path_index) { - PrintToExport print_to_export{prints_to_export[path_index]}; - if (!output_paths[path_index]) { + for (auto &[bed_index, optional_path] : output_paths) { + if (!optional_path) { continue; } - print_to_export.output_path = *output_paths[path_index]; + + const PrintToExport &print_to_export{prints_to_export.at(bed_index)}; + const fs::path &path{*optional_path}; with_mocked_fff_background_process( print_to_export.print, print_to_export.processor_result, @@ -6140,10 +6137,10 @@ void Plater::export_all_gcodes(bool prefer_removable) { [&](){ this->p->background_process.set_temp_output_path(print_to_export.bed); export_gcode_to_path( - print_to_export.output_path, + path, [&](const bool on_removable){ this->p->background_process.finalize_gcode( - print_to_export.output_path.string(), + path.string(), path_on_removable_media ); path_on_removable_media = on_removable || path_on_removable_media; @@ -6729,48 +6726,51 @@ void Plater::connect_gcode_all() { } const PrusaConnectNew connect{*print_host_ptr}; - std::vector paths; + std::vector> paths; for (std::size_t print_index{0}; print_index < this->get_fff_prints().size(); ++print_index) { const std::unique_ptr &print{this->get_fff_prints()[print_index]}; - if (!print || print->empty()) { + if (!print || !is_sliceable(s_print_statuses[print_index])) { continue; } const fs::path filename{upload_job_template.upload_data.upload_path}; - paths.emplace_back( + paths.emplace_back(print_index, fs::path{ filename.stem().string() + "_bed" + std::to_string(print_index + 1) + filename.extension().string() - ); + }); } BulkExportDialog dialog{paths}; if (dialog.ShowModal() != wxID_OK) { return; } - const std::vector> output_paths{dialog.get_paths()}; + const std::vector>> output_paths{dialog.get_paths()}; - for (std::size_t print_index{0}; print_index < this->get_fff_prints().size(); ++print_index) { - if (!output_paths[print_index]) { + for (const auto &key_value : output_paths) { + const int bed_index{key_value.first}; + const std::optional &optional_path{key_value.second}; + if (!optional_path) { continue; } + const fs::path &path{*optional_path}; - const std::unique_ptr &print{this->get_fff_prints()[print_index]}; + const std::unique_ptr &print{this->get_fff_prints()[bed_index]}; if (!print || print->empty()) { continue; } with_mocked_fff_background_process( *print, - this->p->gcode_results[print_index], - print_index, + this->p->gcode_results[bed_index], + bed_index, [&](){ - this->p->background_process.set_temp_output_path(print_index); + this->p->background_process.set_temp_output_path(bed_index); PrintHostJob upload_job; upload_job.upload_data = upload_job_template.upload_data; upload_job.printhost = std::make_unique(connect); upload_job.cancelled = upload_job_template.cancelled; - upload_job.upload_data.upload_path = *output_paths[print_index]; + upload_job.upload_data.upload_path = path; this->p->background_process.prepare_upload(upload_job); } );