Hollowing task triggered by the gizmo now spawns a UI job to not block the UI thread

The AABB tree calculation is still done in the UI thread, so it gets blocked for some time
This commit is contained in:
Lukas Matena 2019-11-07 14:25:03 +01:00
parent 4d8631fef6
commit 9836533cb3
5 changed files with 125 additions and 72 deletions

View file

@ -33,6 +33,7 @@
#include "libslic3r/Format/3mf.hpp"
#include "libslic3r/GCode/PreviewData.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/OpenVDBUtils.hpp"
#include "libslic3r/Polygon.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/PrintConfig.hpp"
@ -1559,7 +1560,8 @@ struct Plater::priv
enum class Jobs : size_t {
Arrange,
Rotoptimize
Rotoptimize,
Hollow
};
class ArrangeJob : public Job
@ -1703,6 +1705,20 @@ struct Plater::priv
void process() override;
};
class HollowJob : public Job
{
public:
using Job::Job;
void prepare() override;
void process() override;
void finalize() override;
private:
std::unique_ptr<TriangleMesh> m_output;
const TriangleMesh* m_object_mesh = nullptr;
float m_offset = 0.f;
float m_adaptability = 0.f;
};
// Jobs defined inside the group class will be managed so that only one can
// run at a time. Also, the background process will be stopped if a job is
// started.
@ -1714,6 +1730,7 @@ struct Plater::priv
ArrangeJob arrange_job{m_plater};
RotoptimizeJob rotoptimize_job{m_plater};
HollowJob hollow_job{m_plater};
// To create a new job, just define a new subclass of Job, implement
// the process and the optional prepare() and finalize() methods
@ -1721,7 +1738,8 @@ struct Plater::priv
// if it cannot run concurrently with other jobs in this group
std::vector<std::reference_wrapper<Job>> m_jobs{arrange_job,
rotoptimize_job};
rotoptimize_job,
hollow_job};
public:
ExclusiveJobGroup(priv *_plater) : m_plater(_plater) {}
@ -1816,6 +1834,7 @@ struct Plater::priv
void reset();
void mirror(Axis axis);
void arrange();
void hollow();
void sla_optimize_rotation();
void split_object();
void split_volume();
@ -2703,6 +2722,12 @@ void Plater::priv::arrange()
m_ui_jobs.start(Jobs::Arrange);
}
void Plater::priv::hollow()
{
this->take_snapshot(_(L("Hollow")));
m_ui_jobs.start(Jobs::Hollow);
}
// This method will find an optimal orientation for the currently selected item
// Very similar in nature to the arrange method above...
void Plater::priv::sla_optimize_rotation() {
@ -2834,6 +2859,38 @@ void Plater::priv::RotoptimizeJob::process()
: _(L("Orientation found.")));
}
void Plater::priv::HollowJob::prepare()
{
const GLGizmosManager& gizmo_manager = plater().q->canvas3D()->get_gizmos_manager();
const GLGizmoHollow* gizmo_hollow = dynamic_cast<const GLGizmoHollow*>(gizmo_manager.get_current());
assert(gizmo_hollow);
gizmo_hollow->get_hollowing_parameters(&m_object_mesh, m_offset, m_adaptability);
m_output.reset();
}
void Plater::priv::HollowJob::process()
{
Slic3r::sla::Contour3D imesh{*m_object_mesh};
auto ptr = meshToVolume(imesh, {});
sla::Contour3D omesh = volumeToMesh(*ptr, -m_offset, m_adaptability, true);
if (omesh.empty())
return;
imesh.merge(omesh);
m_output.reset(new TriangleMesh());
*m_output = sla::to_triangle_mesh(imesh);
m_output->require_shared_vertices();
}
void Plater::priv::HollowJob::finalize()
{
const GLGizmosManager& gizmo_manager = plater().q->canvas3D()->get_gizmos_manager();
GLGizmoHollow* gizmo_hollow = dynamic_cast<GLGizmoHollow*>(gizmo_manager.get_current());
assert(gizmo_hollow);
gizmo_hollow->update_hollowed_mesh(std::move(m_output));
}
void Plater::priv::split_object()
{
int obj_idx = get_selected_object_idx();
@ -4661,6 +4718,11 @@ void Plater::export_toolpaths_to_obj() const
p->preview->get_canvas3d()->export_toolpaths_to_obj(into_u8(path).c_str());
}
void Plater::hollow()
{
p->hollow();
}
void Plater::reslice()
{
// Stop arrange and (or) optimize rotation tasks.