slaprint with dummy backround processing in plater.
This commit is contained in:
parent
91a79e0343
commit
3b373a55e6
@ -137,6 +137,7 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent)
|
||||
: m_parent(parent)
|
||||
, m_group_id(-1)
|
||||
, m_state(Off)
|
||||
, m_prev_state(Off)
|
||||
, m_hover_id(-1)
|
||||
, m_dragging(false)
|
||||
{
|
||||
@ -1621,32 +1622,6 @@ void GLGizmoSlaSupports::update_mesh()
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoSlaSupports::on_deactivate() {
|
||||
if(!m_model_object) return;
|
||||
|
||||
// sla::Controller supportctl;
|
||||
// std::cout << "Generating supports:" << std::endl;
|
||||
|
||||
// // TODO: somehow get the global status indicator
|
||||
// supportctl.statuscb = [] (unsigned st, const std::string& msg) {
|
||||
// std::cout << st << "% " << msg << std::endl;
|
||||
// };
|
||||
|
||||
// TriangleMesh&& m = m_model_object->raw_mesh();
|
||||
// m.transform(m_model_object_matrix);
|
||||
// auto emesh = sla::to_eigenmesh(m);
|
||||
|
||||
// sla::SupportConfig cfg;
|
||||
// sla::PointSet input = sla::support_points(*m_model_object, 0 /*instance*/);
|
||||
|
||||
// sla::SLASupportTree stree(input, emesh, cfg, supportctl);
|
||||
|
||||
// TriangleMesh output;
|
||||
// stree.merged_mesh(output);
|
||||
|
||||
// _3DScene::reload_scene(m_parent.get_wxglcanvas(), false);
|
||||
}
|
||||
|
||||
Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
|
||||
{
|
||||
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
|
||||
|
@ -56,7 +56,7 @@ protected:
|
||||
GLCanvas3D& m_parent;
|
||||
|
||||
int m_group_id;
|
||||
EState m_state;
|
||||
EState m_state, m_prev_state;
|
||||
// textures are assumed to be square and all with the same size in pixels, no internal check is done
|
||||
GLTexture m_textures[Num_States];
|
||||
int m_hover_id;
|
||||
@ -79,12 +79,14 @@ public:
|
||||
|
||||
EState get_state() const { return m_state; }
|
||||
void set_state(EState state) {
|
||||
// FIXME: this is my workaround to react on the disabling event (Tamas)
|
||||
bool call_deactivate = ((m_state == On || m_state == Hover) &&
|
||||
state == Off);
|
||||
bool call_deactivate =
|
||||
m_prev_state == On && state == Off && m_state == Hover;
|
||||
|
||||
if(state == On || state == Off) m_prev_state = state;
|
||||
|
||||
m_state = state; on_set_state();
|
||||
|
||||
// FIXME: this is my workaround to react on the disabling event (Tamas)
|
||||
if(call_deactivate) {
|
||||
on_deactivate();
|
||||
}
|
||||
|
@ -842,6 +842,42 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi
|
||||
|
||||
// Plater / private
|
||||
|
||||
|
||||
// For the SLAPrint: No multi-threading here
|
||||
class DummyBackgroundProcess: public BackgroundProcess {
|
||||
public:
|
||||
|
||||
/// schedule a task on the background
|
||||
virtual void schedule(std::function<void()> fn) override {
|
||||
/*std::asynch*/ fn();
|
||||
}
|
||||
|
||||
/// Report status change, used inside the worker thread
|
||||
virtual void status(unsigned st, const std::string& msg) {
|
||||
// TODO would use the statusbar gauge
|
||||
std::cout << "Processing " << st << "% " << msg << std::endl;
|
||||
}
|
||||
|
||||
/// Check whether the calculation was canceled from the UI. Called by the
|
||||
/// worker thread
|
||||
virtual bool is_canceled() {
|
||||
// this would be connected to the statusbar's cancel button
|
||||
// and return true if that was pushed during the processing
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Determine the state of the background process. If something is running
|
||||
/// returns true. If no job is running, returns false.
|
||||
virtual bool is_running() { return false; }
|
||||
|
||||
virtual void input_changed() override {
|
||||
/*lock();*/
|
||||
BackgroundProcess::input_changed();
|
||||
/*unlock();*/
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Plater::priv
|
||||
{
|
||||
// PIMPL back pointer ("Q-Pointer")
|
||||
@ -854,16 +890,19 @@ struct Plater::priv
|
||||
// Data
|
||||
Slic3r::DynamicPrintConfig *config;
|
||||
Slic3r::Print print;
|
||||
Slic3r::SLAPrint slaprint;
|
||||
Slic3r::Model model;
|
||||
Slic3r::GCodePreviewData gcode_preview_data;
|
||||
|
||||
// Will live only in this branch:
|
||||
Slic3r::SLAPrint slaprint;
|
||||
|
||||
// GUI elements
|
||||
wxNotebook *notebook;
|
||||
Sidebar *sidebar;
|
||||
wxGLCanvas *canvas3D; // TODO: Use GLCanvas3D when we can
|
||||
Preview *preview;
|
||||
BackgroundSlicingProcess background_process;
|
||||
|
||||
wxTimer background_process_timer;
|
||||
|
||||
static const std::regex pattern_bundle;
|
||||
@ -943,7 +982,6 @@ private:
|
||||
const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_3mf(".*3mf", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_zip_amf(".*[.]zip[.]amf", std::regex::icase);
|
||||
|
||||
Plater::priv::priv(Plater *q, MainFrame *main_frame) :
|
||||
q(q),
|
||||
main_frame(main_frame),
|
||||
@ -959,6 +997,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) :
|
||||
canvas3D(GLCanvas3DManager::create_wxglcanvas(notebook)),
|
||||
slaprint(&model)
|
||||
{
|
||||
slaprint.set_scheduler(std::make_shared<DummyBackgroundProcess>());
|
||||
// TODO: background_process.set_print(&slaprint);
|
||||
background_process.set_print(&print);
|
||||
background_process.set_gcode_preview_data(&gcode_preview_data);
|
||||
background_process.set_sliced_event(EVT_SLICING_COMPLETED);
|
||||
@ -1526,6 +1566,10 @@ void Plater::priv::async_apply_config()
|
||||
|
||||
// Apply new config to the possibly running background task.
|
||||
Print::ApplyStatus invalidated = this->background_process.apply(this->q->model(), std::move(config));
|
||||
|
||||
// Thread safe invalidation of the SLAPrint data cache
|
||||
this->slaprint.synch();
|
||||
|
||||
// Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile.
|
||||
if (Slic3r::_3DScene::is_layers_editing_enabled(this->canvas3D))
|
||||
this->canvas3D->Refresh();
|
||||
@ -1936,6 +1980,11 @@ Sidebar& Plater::sidebar() { return *p->sidebar; }
|
||||
Model& Plater::model() { return p->model; }
|
||||
Print& Plater::print() { return p->print; }
|
||||
|
||||
SLAPrint &Plater::sla_print()
|
||||
{
|
||||
return p->slaprint;
|
||||
}
|
||||
|
||||
void Plater::add()
|
||||
{
|
||||
wxArrayString input_files;
|
||||
|
@ -18,6 +18,7 @@ namespace Slic3r {
|
||||
|
||||
class Model;
|
||||
class Print;
|
||||
class SLAPrint;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
@ -104,6 +105,7 @@ public:
|
||||
Sidebar& sidebar();
|
||||
Model& model();
|
||||
Print& print();
|
||||
SLAPrint& sla_print();
|
||||
|
||||
void add();
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include "SLAPrint.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "GLGizmo.hpp"
|
||||
#include "Plater.hpp"
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -16,20 +20,57 @@ const std::string SLAPrint::m_stage_labels[] = {
|
||||
L("SLA print preparation aborted") // ABORT,
|
||||
};
|
||||
|
||||
void SLAPrint::synch() {
|
||||
m_gcfg = m_config_reader();
|
||||
// TODO: check model objects and instances
|
||||
void SLAPrint::_start()
|
||||
{
|
||||
}
|
||||
|
||||
bool SLAPrint::start(std::shared_ptr<BackgroundProcess> scheduler) {
|
||||
if(!m_process || !m_process->is_running()) set_scheduler(scheduler);
|
||||
void SLAPrint::_synch() {
|
||||
m_gcfg = m_config_reader();
|
||||
// TODO: fill PrintObject cache
|
||||
m_dirty.store(false);
|
||||
}
|
||||
|
||||
bool SLAPrint::start() {
|
||||
if(!m_process) return false;
|
||||
|
||||
m_process->schedule([this, scheduler](){
|
||||
|
||||
});
|
||||
m_process->schedule([this](){ _start(); });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace GUI {
|
||||
|
||||
void GLGizmoSlaSupports::on_deactivate() {
|
||||
std::cout << "gizmo deactivated " << std::endl;
|
||||
if(!m_model_object) return;
|
||||
|
||||
SLAPrint& print = wxGetApp().plater()->sla_print();
|
||||
print.synch();
|
||||
|
||||
print.start();
|
||||
|
||||
// sla::Controller supportctl;
|
||||
// std::cout << "Generating supports:" << std::endl;
|
||||
|
||||
// // TODO: somehow get the global status indicator
|
||||
// supportctl.statuscb = [] (unsigned st, const std::string& msg) {
|
||||
// std::cout << st << "% " << msg << std::endl;
|
||||
// };
|
||||
|
||||
// TriangleMesh&& m = m_model_object->raw_mesh();
|
||||
// m.transform(m_model_object_matrix);
|
||||
// auto emesh = sla::to_eigenmesh(m);
|
||||
|
||||
// sla::SupportConfig cfg;
|
||||
// sla::PointSet input = sla::support_points(*m_model_object, 0 /*instance*/);
|
||||
|
||||
// sla::SLASupportTree stree(input, emesh, cfg, supportctl);
|
||||
|
||||
// TriangleMesh output;
|
||||
// stree.merged_mesh(output);
|
||||
|
||||
// _3DScene::reload_scene(m_parent.get_wxglcanvas(), false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ class DynamicPrintConfig;
|
||||
// implemented using a BackgroundSlicingProcess or something derived from that
|
||||
// The methods should be thread safe, obviously...
|
||||
class BackgroundProcess {
|
||||
std::function<void()> m_synchfn;
|
||||
public:
|
||||
|
||||
virtual ~BackgroundProcess() {}
|
||||
@ -33,14 +34,21 @@ public:
|
||||
/// worker thread
|
||||
virtual bool is_canceled() = 0;
|
||||
|
||||
/// Setting up a callback that transfers the input parameters to the worker
|
||||
/// thread. Appropriate synchronization has to be implemented here. A simple
|
||||
/// condition variable and mutex pair should do the job.
|
||||
virtual void on_input_changed(std::function<void()> synchfn) = 0;
|
||||
|
||||
/// Determine the state of the background process. If something is running
|
||||
/// returns true. If no job is running, returns false.
|
||||
virtual bool is_running() = 0;
|
||||
|
||||
/// Trigger the synchronization of frontend/backend data
|
||||
virtual void input_changed() {
|
||||
m_synchfn(); // will just call the provided synch function itself.
|
||||
}
|
||||
|
||||
/// Setting up a callback that transfers the input parameters to the worker
|
||||
/// thread. Appropriate synchronization has to be implemented here. A simple
|
||||
/// condition variable and mutex pair should do the job.
|
||||
void on_input_changed(std::function<void()> synchfn) {
|
||||
m_synchfn = synchfn;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -78,21 +86,20 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
// There will be a support tree for every instance of every ModelObject
|
||||
// because if the object is rotated differently, the support should also be
|
||||
// very different
|
||||
// Caching instance transformations and slices
|
||||
struct PrintObjectInstance {
|
||||
Transform3f tr;
|
||||
std::unique_ptr<sla::SLASupportTree> support_tree_ptr;
|
||||
SlicedSupports slice_cache;
|
||||
};
|
||||
|
||||
using InstanceMap = std::unordered_map<ModelInstance*, PrintObjectInstance>;
|
||||
|
||||
// Every ModelObject will have its PrintObject here. It will contain the
|
||||
// cached index-triangle structure (emesh) and the map of the instance cache
|
||||
// support tree geometry, the cached index-triangle structure (emesh) and
|
||||
// the map of the instance cache
|
||||
struct PrintObject {
|
||||
sla::EigenMesh3D emesh;
|
||||
std::unique_ptr<sla::SLASupportTree> support_tree_ptr;
|
||||
InstanceMap instances;
|
||||
};
|
||||
|
||||
@ -113,19 +120,8 @@ private:
|
||||
std::shared_ptr<BackgroundProcess> m_process; // The scheduler
|
||||
|
||||
// For now it will just stop the whole process and invalidate everything
|
||||
void synch();
|
||||
std::atomic<bool> m_dirty;
|
||||
|
||||
void set_scheduler(std::shared_ptr<BackgroundProcess> scheduler) {
|
||||
if(scheduler && !scheduler->is_running()) {
|
||||
m_process = scheduler;
|
||||
m_process->on_input_changed([this] {
|
||||
/*synch(); */
|
||||
m_dirty.store(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
enum Stages {
|
||||
IDLE,
|
||||
FIND_ROTATION,
|
||||
@ -142,22 +138,35 @@ private:
|
||||
|
||||
static const std::string m_stage_labels[NUM_STAGES];
|
||||
|
||||
bool run();
|
||||
void _start();
|
||||
void _synch();
|
||||
|
||||
public:
|
||||
|
||||
void set_scheduler(std::shared_ptr<BackgroundProcess> scheduler) {
|
||||
if(scheduler && !scheduler->is_running()) {
|
||||
m_process = scheduler;
|
||||
m_process->on_input_changed([this] {
|
||||
_synch();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SLAPrint(const Model * model,
|
||||
std::function<SLAPrint::GlobalConfig(void)> cfgreader =
|
||||
[](){ return SLAPrint::GlobalConfig(); },
|
||||
std::shared_ptr<BackgroundProcess> scheduler = {}):
|
||||
m_model(model), m_config_reader(cfgreader)
|
||||
{
|
||||
synch();
|
||||
m_dirty.store(false);
|
||||
set_scheduler(scheduler);
|
||||
}
|
||||
|
||||
void synch() {
|
||||
if(m_process) m_process->input_changed();
|
||||
}
|
||||
|
||||
// This will start the calculation using the
|
||||
bool start(std::shared_ptr<BackgroundProcess> scheduler);
|
||||
bool start();
|
||||
|
||||
// Get the full support structure (including the base pool)
|
||||
// This should block until the supports are not ready?
|
||||
|
Loading…
Reference in New Issue
Block a user