mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-25 11:52:05 +00:00
Port Emboss & SVG gizmo from PrusaSlicer (#2819)
* Rework UI jobs to make them more understandable and flexible. * Update Orca specific jobs * Fix progress issue * Fix dark mode and window radius * Update cereal version from 1.2.2 to 1.3.0 (cherry picked from commit prusa3d/PrusaSlicer@057232a275) * Initial port of Emboss gizmo * Bump up CGAL version to 5.4 (cherry picked from commit prusa3d/PrusaSlicer@1bf9dee3e7) * Fix text rotation * Fix test dragging * Add text gizmo to right click menu * Initial port of SVG gizmo * Fix text rotation * Fix Linux build * Fix "from surface" * Fix -90 rotation * Fix icon path * Fix loading font with non-ascii name * Fix storing non-utf8 font descriptor in 3mf file * Fix filtering with non-utf8 characters * Emboss: Use Orca style input dialog * Fix build on macOS * Fix tooltip color in light mode * InputText: fixed incorrect padding when FrameBorder > 0. (ocornut/imgui#4794, ocornut/imgui#3781) InputTextMultiline: fixed vertical tracking with large values of FramePadding.y. (ocornut/imgui#3781, ocornut/imgui#4794) (cherry picked from commit ocornut/imgui@072caa4a90) (cherry picked from commit ocornut/imgui@bdd2a94315) * SVG: Use Orca style input dialog * Fix job progress update * Fix crash when select editing text in preview screen * Use Orca checkbox style * Fix issue that toolbar icons are kept regenerated * Emboss: Fix text & icon alignment * SVG: Fix text & icon alignment * Emboss: fix toolbar icon mouse hover state * Add a simple subtle outline effect by drawing back faces using wireframe mode * Disable selection outlines * Show outline in white if the model color is too dark * Make the outline algorithm more reliable * Enable cull face, which fix render on Linux * Fix `disable_cullface` * Post merge fix * Optimize selection rendering * Fix scale gizmo * Emboss: Fix text rotation if base object is scaled * Fix volume synchronize * Fix emboss rotation * Emboss: Fix advance toggle * Fix text position after reopened the project * Make font style preview darker * Make font style preview selector height shorter --------- Co-authored-by: tamasmeszaros <meszaros.q@gmail.com> Co-authored-by: ocornut <omarcornut@gmail.com> Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
159
src/slic3r/GUI/Jobs/BoostThreadWorker.hpp
Normal file
159
src/slic3r/GUI/Jobs/BoostThreadWorker.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
///|/ Copyright (c) Prusa Research 2021 Tomáš Mészáros @tamasmeszaros
|
||||
///|/
|
||||
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef BOOSTTHREADWORKER_HPP
|
||||
#define BOOSTTHREADWORKER_HPP
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
#include "Worker.hpp"
|
||||
|
||||
#include <libslic3r/Thread.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "ThreadSafeQueue.hpp"
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
// An implementation of the Worker interface which uses the boost::thread
|
||||
// API and two thread safe message queues to communicate with the main thread
|
||||
// back and forth. The queue from the main thread to the worker thread holds the
|
||||
// job entries that will be performed on the worker. The other queue holds messages
|
||||
// from the worker to the main thread. These messages include status updates,
|
||||
// finishing operation and arbitrary functiors that need to be performed
|
||||
// on the main thread during the jobs execution, like displaying intermediate
|
||||
// results.
|
||||
class BoostThreadWorker : public Worker, private Job::Ctl
|
||||
{
|
||||
struct JobEntry // Goes into worker and also out of worker as a finalize msg
|
||||
{
|
||||
std::unique_ptr<Job> job;
|
||||
bool canceled = false;
|
||||
std::exception_ptr eptr = nullptr;
|
||||
};
|
||||
|
||||
// A message data for status updates. Only goes from worker to main thread.
|
||||
struct StatusInfo { int status; std::string msg; };
|
||||
|
||||
// An arbitrary callback to be called on the main thread. Only from worker
|
||||
// to main thread.
|
||||
struct MainThreadCallData
|
||||
{
|
||||
std::function<void()> fn;
|
||||
std::promise<void> promise;
|
||||
};
|
||||
|
||||
struct EmptyMessage {};
|
||||
|
||||
class WorkerMessage
|
||||
{
|
||||
public:
|
||||
enum MsgType { Empty, Status, Finalize, MainThreadCall };
|
||||
|
||||
private:
|
||||
boost::variant<EmptyMessage, StatusInfo, JobEntry, MainThreadCallData> m_data;
|
||||
|
||||
public:
|
||||
WorkerMessage() = default;
|
||||
WorkerMessage(int s, std::string txt)
|
||||
: m_data{StatusInfo{s, std::move(txt)}}
|
||||
{}
|
||||
WorkerMessage(JobEntry &&entry) : m_data{std::move(entry)} {}
|
||||
WorkerMessage(MainThreadCallData fn) : m_data{std::move(fn)} {}
|
||||
|
||||
int get_type () const { return m_data.which(); }
|
||||
|
||||
void deliver(BoostThreadWorker &runner);
|
||||
};
|
||||
|
||||
using JobQueue = ThreadSafeQueueSPSC<JobEntry>;
|
||||
using MessageQueue = ThreadSafeQueueSPSC<WorkerMessage>;
|
||||
|
||||
boost::thread m_thread;
|
||||
std::atomic<bool> m_running{false}, m_canceled{false};
|
||||
std::shared_ptr<ProgressIndicator> m_progress;
|
||||
JobQueue m_input_queue; // from main thread to worker
|
||||
MessageQueue m_output_queue; // form worker to main thread
|
||||
std::string m_name;
|
||||
|
||||
void run();
|
||||
|
||||
bool join(int timeout_ms = 0);
|
||||
|
||||
protected:
|
||||
// Implement Job::Ctl interface:
|
||||
|
||||
void update_status(int st, const std::string &msg = "") override;
|
||||
|
||||
bool was_canceled() const override { return m_canceled.load(); }
|
||||
|
||||
std::future<void> call_on_main_thread(std::function<void()> fn) override;
|
||||
|
||||
public:
|
||||
explicit BoostThreadWorker(std::shared_ptr<ProgressIndicator> pri,
|
||||
boost::thread::attributes & attr,
|
||||
const char * name = "");
|
||||
|
||||
explicit BoostThreadWorker(std::shared_ptr<ProgressIndicator> pri,
|
||||
boost::thread::attributes && attr,
|
||||
const char * name = "")
|
||||
: BoostThreadWorker{std::move(pri), attr, name}
|
||||
{}
|
||||
|
||||
explicit BoostThreadWorker(std::shared_ptr<ProgressIndicator> pri,
|
||||
const char * name = "")
|
||||
: BoostThreadWorker{std::move(pri), {}, name}
|
||||
{}
|
||||
|
||||
~BoostThreadWorker();
|
||||
|
||||
BoostThreadWorker(const BoostThreadWorker &) = delete;
|
||||
BoostThreadWorker(BoostThreadWorker &&) = delete;
|
||||
BoostThreadWorker &operator=(const BoostThreadWorker &) = delete;
|
||||
BoostThreadWorker &operator=(BoostThreadWorker &&) = delete;
|
||||
|
||||
bool push(std::unique_ptr<Job> job) override;
|
||||
|
||||
bool is_idle() const override
|
||||
{
|
||||
// The assumption is that jobs can only be queued from a single main
|
||||
// thread from which this method is also called. And the output
|
||||
// messages are also processed only in this calling thread. In that
|
||||
// case, if the input queue is empty, it will remain so during this
|
||||
// function call. If the worker thread is also not running and the
|
||||
// output queue is already processed, we can safely say that the
|
||||
// worker is dormant.
|
||||
return m_input_queue.empty() && !m_running.load() && m_output_queue.empty();
|
||||
}
|
||||
|
||||
void cancel() override { m_canceled.store(true); }
|
||||
void cancel_all() override { m_input_queue.clear(); cancel(); }
|
||||
|
||||
ProgressIndicator * get_pri() { return m_progress.get(); }
|
||||
const ProgressIndicator * get_pri() const { return m_progress.get(); }
|
||||
|
||||
void clear_percent() override
|
||||
{
|
||||
if (m_progress) {
|
||||
m_progress->clear_percent();
|
||||
}
|
||||
}
|
||||
|
||||
void show_error_info(const std::string &msg, int code, const std::string &description, const std::string &extra) override
|
||||
{
|
||||
if (m_progress) {
|
||||
m_progress->show_error_info(from_u8(msg), code, from_u8(description), from_u8(extra));
|
||||
}
|
||||
}
|
||||
|
||||
void process_events() override;
|
||||
bool wait_for_current_job(unsigned timeout_ms = 0) override;
|
||||
bool wait_for_idle(unsigned timeout_ms = 0) override;
|
||||
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif // BOOSTTHREADWORKER_HPP
|
||||
Reference in New Issue
Block a user