mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-17 11:35:56 +08:00
Added progress bar and cancellation into UI, seq arrange is now executed from the main toolbar
This commit is contained in:
parent
dc7ea52d88
commit
c9b3f29c5b
@ -79,6 +79,7 @@ src/slic3r/GUI/GUI_Preview.cpp
|
|||||||
src/slic3r/GUI/HintNotification.cpp
|
src/slic3r/GUI/HintNotification.cpp
|
||||||
src/slic3r/GUI/ImGuiWrapper.cpp
|
src/slic3r/GUI/ImGuiWrapper.cpp
|
||||||
src/slic3r/GUI/Jobs/ArrangeJob2.cpp
|
src/slic3r/GUI/Jobs/ArrangeJob2.cpp
|
||||||
|
src/slic3r/GUI/Jobs/SeqArrangeJob.cpp
|
||||||
src/slic3r/GUI/Jobs/EmbossJob.cpp
|
src/slic3r/GUI/Jobs/EmbossJob.cpp
|
||||||
src/slic3r/GUI/Jobs/PlaterWorker.hpp
|
src/slic3r/GUI/Jobs/PlaterWorker.hpp
|
||||||
src/slic3r/GUI/Jobs/RotoptimizeJob.hpp
|
src/slic3r/GUI/Jobs/RotoptimizeJob.hpp
|
||||||
|
@ -250,6 +250,8 @@ set(SLIC3R_GUI_SOURCES
|
|||||||
GUI/Jobs/PlaterWorker.hpp
|
GUI/Jobs/PlaterWorker.hpp
|
||||||
GUI/Jobs/ArrangeJob2.hpp
|
GUI/Jobs/ArrangeJob2.hpp
|
||||||
GUI/Jobs/ArrangeJob2.cpp
|
GUI/Jobs/ArrangeJob2.cpp
|
||||||
|
GUI/Jobs/SeqArrangeJob.hpp
|
||||||
|
GUI/Jobs/SeqArrangeJob.cpp
|
||||||
GUI/Jobs/CreateFontNameImageJob.cpp
|
GUI/Jobs/CreateFontNameImageJob.cpp
|
||||||
GUI/Jobs/CreateFontNameImageJob.hpp
|
GUI/Jobs/CreateFontNameImageJob.hpp
|
||||||
GUI/Jobs/CreateFontStyleImagesJob.cpp
|
GUI/Jobs/CreateFontStyleImagesJob.cpp
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "libseqarrange/seq_interface.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
@ -79,17 +78,36 @@ static std::vector<Sequential::ObjectToPrint> get_objects_to_print(const Model&
|
|||||||
|
|
||||||
void arrange_model_sequential(Model& model)
|
void arrange_model_sequential(Model& model)
|
||||||
{
|
{
|
||||||
Sequential::PrinterGeometry printer_geometry = get_printer_geometry();
|
SeqArrange seq_arrange(model);
|
||||||
Sequential::SolverConfiguration solver_config = get_solver_config(printer_geometry);
|
seq_arrange.process_seq_arrange([](int) {});
|
||||||
std::vector<Sequential::ObjectToPrint> objects = get_objects_to_print(model, printer_geometry);
|
seq_arrange.apply_seq_arrange(model);
|
||||||
|
}
|
||||||
|
|
||||||
// Everything ready - let libseqarrange do the actual arrangement.
|
|
||||||
std::vector<Sequential::ScheduledPlate> plates =
|
|
||||||
|
SeqArrange::SeqArrange(const Model& model)
|
||||||
|
{
|
||||||
|
m_printer_geometry = get_printer_geometry();
|
||||||
|
m_solver_configuration = get_solver_config(m_printer_geometry);
|
||||||
|
m_objects = get_objects_to_print(model, m_printer_geometry);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SeqArrange::process_seq_arrange(std::function<void(int)> progress_fn)
|
||||||
|
{
|
||||||
|
m_plates =
|
||||||
Sequential::schedule_ObjectsForSequentialPrint(
|
Sequential::schedule_ObjectsForSequentialPrint(
|
||||||
solver_config,
|
m_solver_configuration,
|
||||||
printer_geometry,
|
m_printer_geometry,
|
||||||
objects);
|
m_objects, progress_fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SeqArrange::apply_seq_arrange(Model& model) const
|
||||||
|
{
|
||||||
// Extract the result and move the objects in Model accordingly.
|
// Extract the result and move the objects in Model accordingly.
|
||||||
struct MoveData {
|
struct MoveData {
|
||||||
Sequential::ScheduledObject scheduled_object;
|
Sequential::ScheduledObject scheduled_object;
|
||||||
@ -102,7 +120,7 @@ void arrange_model_sequential(Model& model)
|
|||||||
// Now iterate through all the files, read the data and move the objects accordingly.
|
// Now iterate through all the files, read the data and move the objects accordingly.
|
||||||
// Save the move data from this file to move_data_all.
|
// Save the move data from this file to move_data_all.
|
||||||
size_t bed_idx = 0;
|
size_t bed_idx = 0;
|
||||||
for (const Sequential::ScheduledPlate& plate : plates) {
|
for (const Sequential::ScheduledPlate& plate : m_plates) {
|
||||||
Vec3d bed_offset = s_multiple_beds.get_bed_translation(bed_idx);
|
Vec3d bed_offset = s_multiple_beds.get_bed_translation(bed_idx);
|
||||||
// Iterate the same way as when exporting.
|
// Iterate the same way as when exporting.
|
||||||
for (ModelObject* mo : model.objects) {
|
for (ModelObject* mo : model.objects) {
|
||||||
@ -130,6 +148,10 @@ void arrange_model_sequential(Model& model)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool check_seq_printability(const Model& model)
|
bool check_seq_printability(const Model& model)
|
||||||
{
|
{
|
||||||
Sequential::PrinterGeometry printer_geometry = get_printer_geometry();
|
Sequential::PrinterGeometry printer_geometry = get_printer_geometry();
|
||||||
|
@ -1,11 +1,37 @@
|
|||||||
#ifndef slic3r_Arrange_Helper_hpp
|
#ifndef slic3r_Arrange_Helper_hpp
|
||||||
#define slic3r_Arrange_Helper_hpp
|
#define slic3r_Arrange_Helper_hpp
|
||||||
|
|
||||||
class Model;
|
#include "libseqarrange/seq_interface.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class Model;
|
||||||
|
|
||||||
void arrange_model_sequential(Model& model);
|
void arrange_model_sequential(Model& model);
|
||||||
bool check_seq_printability(const Model& model);
|
bool check_seq_printability(const Model& model);
|
||||||
|
|
||||||
|
|
||||||
|
// This is just a helper class to collect data for seq. arrangement, running the arrangement
|
||||||
|
// and applying the results to model. It is here so the processing itself can be offloaded
|
||||||
|
// into a separate thread without copying the Model or sharing it with UI thread.
|
||||||
|
class SeqArrange {
|
||||||
|
public:
|
||||||
|
explicit SeqArrange(const Model& model);
|
||||||
|
void process_seq_arrange(std::function<void(int)> progress_fn);
|
||||||
|
void apply_seq_arrange(Model& model) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Following three are inputs, filled in by the constructor.
|
||||||
|
Sequential::PrinterGeometry m_printer_geometry;
|
||||||
|
Sequential::SolverConfiguration m_solver_configuration;
|
||||||
|
std::vector<Sequential::ObjectToPrint> m_objects;
|
||||||
|
|
||||||
|
// This is the output, filled in by process_seq_arrange.
|
||||||
|
std::vector<Sequential::ScheduledPlate> m_plates;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // slic3r_Arrange_Helper_hpp
|
#endif // slic3r_Arrange_Helper_hpp
|
@ -2223,23 +2223,14 @@ void GLCanvas3D::render()
|
|||||||
{
|
{
|
||||||
// This is just temporary pipe to export data to the separate arrange algorithm
|
// This is just temporary pipe to export data to the separate arrange algorithm
|
||||||
// and importing the result back. TESTING ONLY !!!
|
// and importing the result back. TESTING ONLY !!!
|
||||||
ImGui::Begin("TESTING ONLY (arrange)");
|
|
||||||
if (ImGui::Button("Do sequential arrange")) {
|
|
||||||
arrange_model_sequential(wxGetApp().plater()->model());
|
|
||||||
reload_scene(true, true);
|
|
||||||
wxGetApp().obj_list()->update_after_undo_redo();
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto time_start = std::chrono::high_resolution_clock::now();
|
static auto time_start = std::chrono::high_resolution_clock::now();
|
||||||
auto time_now = std::chrono::high_resolution_clock::now();
|
auto time_now = std::chrono::high_resolution_clock::now();
|
||||||
int time_limit_s = 1;
|
int time_limit_s = 1;
|
||||||
static bool last_res = 0;
|
static bool last_res = 0;
|
||||||
bool valid = std::chrono::duration_cast<std::chrono::seconds>(time_now - time_start).count() < time_limit_s;
|
bool valid = std::chrono::duration_cast<std::chrono::seconds>(time_now - time_start).count() < time_limit_s;
|
||||||
|
|
||||||
ImGui::Text("");
|
ImGui::Begin("TESTING ONLY (arrange)");
|
||||||
ImGui::Separator();
|
if (ImGui::Button("Test seq printability:")) {
|
||||||
ImGui::Text("");
|
|
||||||
if (ImGui::Button("Test:")) {
|
|
||||||
last_res = check_seq_printability(wxGetApp().plater()->model());
|
last_res = check_seq_printability(wxGetApp().plater()->model());
|
||||||
time_start = std::chrono::high_resolution_clock::now();
|
time_start = std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
57
src/slic3r/GUI/Jobs/SeqArrangeJob.cpp
Normal file
57
src/slic3r/GUI/Jobs/SeqArrangeJob.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "SeqArrangeJob.hpp"
|
||||||
|
|
||||||
|
#include "slic3r/GUI/ArrangeHelper.hpp"
|
||||||
|
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||||
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
|
|
||||||
|
SeqArrangeJob::SeqArrangeJob(const Model& model)
|
||||||
|
{
|
||||||
|
m_seq_arrange.reset(new SeqArrange(model));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SeqArrangeJob::process(Ctl& ctl)
|
||||||
|
{
|
||||||
|
class SeqArrangeJobException : std::exception {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_seq_arrange->process_seq_arrange([&](int progress) {
|
||||||
|
ctl.update_status(progress, _u8L("Arranging for sequential print"));
|
||||||
|
if (ctl.was_canceled())
|
||||||
|
throw SeqArrangeJobException();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (const SeqArrangeJobException&) {
|
||||||
|
// The task was canceled. Just make sure that the progress notification disappears.
|
||||||
|
ctl.update_status(100, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SeqArrangeJob::finalize(bool canceled, std::exception_ptr&)
|
||||||
|
{
|
||||||
|
// If the task was cancelled, the stopping exception was already caught
|
||||||
|
// in 'process' function. Let any other exception propagate further.
|
||||||
|
if (! canceled) {
|
||||||
|
m_seq_arrange->apply_seq_arrange(wxGetApp().model());
|
||||||
|
wxGetApp().plater()->canvas3D()->reload_scene(true, true);
|
||||||
|
wxGetApp().obj_list()->update_after_undo_redo();
|
||||||
|
}
|
||||||
|
m_seq_arrange.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace GUI
|
||||||
|
} // namespace Slic3r
|
30
src/slic3r/GUI/Jobs/SeqArrangeJob.hpp
Normal file
30
src/slic3r/GUI/Jobs/SeqArrangeJob.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef SEQARRANGEJOB_HPP
|
||||||
|
#define SEQARRANGEJOB_HPP
|
||||||
|
|
||||||
|
#include "Job.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class Model;
|
||||||
|
|
||||||
|
|
||||||
|
class SeqArrange;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
|
||||||
|
class SeqArrangeJob : public Job
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SeqArrangeJob(const Model& model);
|
||||||
|
virtual void process(Ctl &ctl) override;
|
||||||
|
virtual void finalize(bool /*canceled*/, std::exception_ptr&) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<SeqArrange> m_seq_arrange;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace GUI
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // ARRANGEJOB2_HPP
|
@ -106,6 +106,7 @@
|
|||||||
#include "ConfigWizardWebViewPage.hpp"
|
#include "ConfigWizardWebViewPage.hpp"
|
||||||
|
|
||||||
#include "Jobs/RotoptimizeJob.hpp"
|
#include "Jobs/RotoptimizeJob.hpp"
|
||||||
|
#include "Jobs/SeqArrangeJob.hpp"
|
||||||
#include "Jobs/SLAImportJob.hpp"
|
#include "Jobs/SLAImportJob.hpp"
|
||||||
#include "Jobs/SLAImportDialog.hpp"
|
#include "Jobs/SLAImportDialog.hpp"
|
||||||
#include "Jobs/NotificationProgressIndicator.hpp"
|
#include "Jobs/NotificationProgressIndicator.hpp"
|
||||||
@ -7151,11 +7152,17 @@ void Plater::arrange()
|
|||||||
ArrangeSelectionMode::Full
|
ArrangeSelectionMode::Full
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bool sequential = p->config->has("complete_objects") && p->config->opt_bool("complete_objects");
|
||||||
|
|
||||||
if (p->can_arrange()) {
|
if (p->can_arrange()) {
|
||||||
|
if (sequential)
|
||||||
|
replace_job(this->get_ui_job_worker(), std::make_unique<SeqArrangeJob>(this->model()));
|
||||||
|
else {
|
||||||
auto& w = get_ui_job_worker();
|
auto& w = get_ui_job_worker();
|
||||||
arrange(w, mode);
|
arrange(w, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Plater::arrange_current_bed()
|
void Plater::arrange_current_bed()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user