Implemented another behavior of the "Slice Now" / "Export/Send G-code" buttons (SPE-831)
This commit is contained in:
parent
a76bd40c62
commit
a123099f80
@ -834,6 +834,8 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
|||||||
ModelInstance::EPrintVolumeState state = ModelInstance::PVS_Inside;
|
ModelInstance::EPrintVolumeState state = ModelInstance::PVS_Inside;
|
||||||
bool all_contained = true;
|
bool all_contained = true;
|
||||||
|
|
||||||
|
bool contained_min_one = false;
|
||||||
|
|
||||||
for (GLVolume* volume : this->volumes)
|
for (GLVolume* volume : this->volumes)
|
||||||
{
|
{
|
||||||
if ((volume == nullptr) || volume->is_modifier || (volume->is_wipe_tower && !volume->shader_outside_printer_detection_enabled) || ((volume->composite_id.volume_id < 0) && !volume->shader_outside_printer_detection_enabled))
|
if ((volume == nullptr) || volume->is_modifier || (volume->is_wipe_tower && !volume->shader_outside_printer_detection_enabled) || ((volume->composite_id.volume_id < 0) && !volume->shader_outside_printer_detection_enabled))
|
||||||
@ -843,6 +845,9 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
|||||||
bool contained = print_volume.contains(bb);
|
bool contained = print_volume.contains(bb);
|
||||||
all_contained &= contained;
|
all_contained &= contained;
|
||||||
|
|
||||||
|
if (contained)
|
||||||
|
contained_min_one = true;
|
||||||
|
|
||||||
volume->is_outside = !contained;
|
volume->is_outside = !contained;
|
||||||
|
|
||||||
if ((state == ModelInstance::PVS_Inside) && volume->is_outside)
|
if ((state == ModelInstance::PVS_Inside) && volume->is_outside)
|
||||||
@ -855,7 +860,7 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
|||||||
if (out_state != nullptr)
|
if (out_state != nullptr)
|
||||||
*out_state = state;
|
*out_state = state;
|
||||||
|
|
||||||
return all_contained;
|
return /*all_contained*/ contained_min_one; // #ys_FIXME_delete_after_testing
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVolumeCollection::reset_outside_state()
|
void GLVolumeCollection::reset_outside_state()
|
||||||
|
@ -123,6 +123,9 @@ public:
|
|||||||
// This "finished" flag does not account for the final export of the output file (.gcode or zipped PNGs),
|
// This "finished" flag does not account for the final export of the output file (.gcode or zipped PNGs),
|
||||||
// and it does not account for the OctoPrint scheduling.
|
// and it does not account for the OctoPrint scheduling.
|
||||||
bool finished() const { return m_print->finished(); }
|
bool finished() const { return m_print->finished(); }
|
||||||
|
|
||||||
|
// set status line
|
||||||
|
void set_status(const std::string & status_str) const { m_print->set_status(100, status_str); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void thread_proc();
|
void thread_proc();
|
||||||
|
@ -3067,7 +3067,7 @@ GLGizmoBase* GLCanvas3D::Gizmos::_get_current() const
|
|||||||
return (it != m_gizmos.end()) ? it->second : nullptr;
|
return (it != m_gizmos.end()) ? it->second : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 9, 91, 134 };
|
const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 120, 120, 120 };//{ 9, 91, 134 };
|
||||||
const unsigned char GLCanvas3D::WarningTexture::Opacity = 255;
|
const unsigned char GLCanvas3D::WarningTexture::Opacity = 255;
|
||||||
|
|
||||||
GLCanvas3D::WarningTexture::WarningTexture()
|
GLCanvas3D::WarningTexture::WarningTexture()
|
||||||
@ -3101,16 +3101,23 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool
|
|||||||
|
|
||||||
// Look at the end of our vector and generate proper texture.
|
// Look at the end of our vector and generate proper texture.
|
||||||
std::string text;
|
std::string text;
|
||||||
|
bool red_colored = false;
|
||||||
switch (m_warnings.back()) {
|
switch (m_warnings.back()) {
|
||||||
case ObjectOutside : text = L("Detected object outside print volume"); break;
|
case ObjectOutside : text = L("Detected object outside print volume"); break;
|
||||||
case ToolpathOutside : text = L("Detected toolpath outside print volume"); break;
|
case ToolpathOutside : text = L("Detected toolpath outside print volume"); break;
|
||||||
case SomethingNotShown : text = L("Some objects are not visible when editing supports"); break;
|
case SomethingNotShown : text = L("Some objects are not visible when editing supports"); break;
|
||||||
|
case ObjectClashed: {
|
||||||
|
text = L("Detected object outside print volume\n"
|
||||||
|
"Resolve a clash to continue slicing/export process correctly");
|
||||||
|
red_colored = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_generate(text, canvas); // GUI::GLTexture::reset() is called at the beginning of generate(...)
|
_generate(text, canvas, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanvas3D& canvas)
|
bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanvas3D& canvas, const bool red_colored/* = false*/)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
@ -3127,7 +3134,8 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanva
|
|||||||
|
|
||||||
// calculates texture size
|
// calculates texture size
|
||||||
wxCoord w, h;
|
wxCoord w, h;
|
||||||
memDC.GetTextExtent(msg, &w, &h);
|
// memDC.GetTextExtent(msg, &w, &h);
|
||||||
|
memDC.GetMultiLineTextExtent(msg, &w, &h);
|
||||||
|
|
||||||
int pow_of_two_size = next_highest_power_of_2(std::max<unsigned int>(w, h));
|
int pow_of_two_size = next_highest_power_of_2(std::max<unsigned int>(w, h));
|
||||||
|
|
||||||
@ -3144,8 +3152,9 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanva
|
|||||||
memDC.Clear();
|
memDC.Clear();
|
||||||
|
|
||||||
// draw message
|
// draw message
|
||||||
memDC.SetTextForeground(*wxWHITE);
|
memDC.SetTextForeground(red_colored ? wxColour(255,72,65/*204,204*/) : *wxWHITE);
|
||||||
memDC.DrawText(msg, 0, 0);
|
// memDC.DrawText(msg, 0, 0);
|
||||||
|
memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER);
|
||||||
|
|
||||||
memDC.SelectObject(wxNullBitmap);
|
memDC.SelectObject(wxNullBitmap);
|
||||||
|
|
||||||
@ -4392,23 +4401,33 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||||||
if (!m_volumes.empty())
|
if (!m_volumes.empty())
|
||||||
{
|
{
|
||||||
ModelInstance::EPrintVolumeState state;
|
ModelInstance::EPrintVolumeState state;
|
||||||
bool contained = m_volumes.check_outside_state(m_config, &state);
|
|
||||||
|
|
||||||
if (!contained)
|
const bool contained_min_one = m_volumes.check_outside_state(m_config, &state);
|
||||||
{
|
|
||||||
_set_warning_texture(WarningTexture::ObjectOutside, true);
|
_set_warning_texture(WarningTexture::ObjectClashed, state == ModelInstance::PVS_Partly_Outside);
|
||||||
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, state == ModelInstance::PVS_Fully_Outside));
|
_set_warning_texture(WarningTexture::ObjectOutside, state == ModelInstance::PVS_Fully_Outside);
|
||||||
}
|
|
||||||
else
|
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS,
|
||||||
{
|
contained_min_one && !m_model->objects.empty() && state != ModelInstance::PVS_Partly_Outside));
|
||||||
m_volumes.reset_outside_state();
|
|
||||||
_set_warning_texture(WarningTexture::ObjectOutside, false);
|
// #ys_FIXME_delete_after_testing
|
||||||
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, !m_model->objects.empty()));
|
// bool contained = m_volumes.check_outside_state(m_config, &state);
|
||||||
}
|
// if (!contained)
|
||||||
|
// {
|
||||||
|
// _set_warning_texture(WarningTexture::ObjectOutside, true);
|
||||||
|
// post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, state == ModelInstance::PVS_Fully_Outside));
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// m_volumes.reset_outside_state();
|
||||||
|
// _set_warning_texture(WarningTexture::ObjectOutside, false);
|
||||||
|
// post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, !m_model->objects.empty()));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_set_warning_texture(WarningTexture::ObjectOutside, false);
|
_set_warning_texture(WarningTexture::ObjectOutside, false);
|
||||||
|
_set_warning_texture(WarningTexture::ObjectClashed, false);
|
||||||
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false));
|
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,7 +751,8 @@ private:
|
|||||||
enum Warning {
|
enum Warning {
|
||||||
ObjectOutside,
|
ObjectOutside,
|
||||||
ToolpathOutside,
|
ToolpathOutside,
|
||||||
SomethingNotShown
|
SomethingNotShown,
|
||||||
|
ObjectClashed
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sets a warning of the given type to be active/inactive. If several warnings are active simultaneously,
|
// Sets a warning of the given type to be active/inactive. If several warnings are active simultaneously,
|
||||||
@ -770,7 +771,7 @@ private:
|
|||||||
std::vector<Warning> m_warnings;
|
std::vector<Warning> m_warnings;
|
||||||
|
|
||||||
// Generates the texture with given text.
|
// Generates the texture with given text.
|
||||||
bool _generate(const std::string& msg, const GLCanvas3D& canvas);
|
bool _generate(const std::string& msg, const GLCanvas3D& canvas, const bool red_colored = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
class LegendTexture : public GUI::GLTexture
|
class LegendTexture : public GUI::GLTexture
|
||||||
|
@ -881,9 +881,10 @@ void MainFrame::on_config_changed(DynamicPrintConfig* config) const
|
|||||||
// Update the UI based on the current preferences.
|
// Update the UI based on the current preferences.
|
||||||
void MainFrame::update_ui_from_settings()
|
void MainFrame::update_ui_from_settings()
|
||||||
{
|
{
|
||||||
bool bp_on = wxGetApp().app_config->get("background_processing") == "1";
|
const bool bp_on = wxGetApp().app_config->get("background_processing") == "1";
|
||||||
// m_menu_item_reslice_now->Enable(!bp_on);
|
// m_menu_item_reslice_now->Enable(!bp_on);
|
||||||
m_plater->sidebar().show_reslice(!bp_on);
|
m_plater->sidebar().show_reslice(!bp_on);
|
||||||
|
m_plater->sidebar().show_export(bp_on);
|
||||||
m_plater->sidebar().Layout();
|
m_plater->sidebar().Layout();
|
||||||
if (m_plater)
|
if (m_plater)
|
||||||
m_plater->update_ui_from_settings();
|
m_plater->update_ui_from_settings();
|
||||||
|
@ -487,6 +487,12 @@ ConfigOptionsGroup* FreqChangedParams::get_og(const bool is_fff)
|
|||||||
|
|
||||||
// Sidebar / private
|
// Sidebar / private
|
||||||
|
|
||||||
|
enum class ActionButtonType : int {
|
||||||
|
abReslice,
|
||||||
|
abExport,
|
||||||
|
abSendGCode
|
||||||
|
};
|
||||||
|
|
||||||
struct Sidebar::priv
|
struct Sidebar::priv
|
||||||
{
|
{
|
||||||
Plater *plater;
|
Plater *plater;
|
||||||
@ -942,8 +948,9 @@ void Sidebar::enable_buttons(bool enable)
|
|||||||
p->btn_send_gcode->Enable(enable);
|
p->btn_send_gcode->Enable(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sidebar::show_reslice(bool show) { p->btn_reslice->Show(show); }
|
void Sidebar::show_reslice(bool show) const { p->btn_reslice->Show(show); }
|
||||||
void Sidebar::show_send(bool show) { p->btn_send_gcode->Show(show); }
|
void Sidebar::show_export(bool show) const { p->btn_export_gcode->Show(show); }
|
||||||
|
void Sidebar::show_send(bool show) const { p->btn_send_gcode->Show(show); }
|
||||||
|
|
||||||
bool Sidebar::is_multifilament()
|
bool Sidebar::is_multifilament()
|
||||||
{
|
{
|
||||||
@ -1033,6 +1040,8 @@ struct Plater::priv
|
|||||||
|
|
||||||
wxTimer background_process_timer;
|
wxTimer background_process_timer;
|
||||||
|
|
||||||
|
std::string label_btn_export;
|
||||||
|
|
||||||
static const std::regex pattern_bundle;
|
static const std::regex pattern_bundle;
|
||||||
static const std::regex pattern_3mf;
|
static const std::regex pattern_3mf;
|
||||||
static const std::regex pattern_zip_amf;
|
static const std::regex pattern_zip_amf;
|
||||||
@ -1122,6 +1131,7 @@ struct Plater::priv
|
|||||||
void on_3dcanvas_mouse_dragging_finished(SimpleEvent&);
|
void on_3dcanvas_mouse_dragging_finished(SimpleEvent&);
|
||||||
|
|
||||||
void update_object_menu();
|
void update_object_menu();
|
||||||
|
void show_action_buttons(const bool is_ready_to_slice) const;
|
||||||
|
|
||||||
// Set the bed shape to a single closed 2D polygon(array of two element arrays),
|
// Set the bed shape to a single closed 2D polygon(array of two element arrays),
|
||||||
// triangulate the bed and store the triangles into m_bed.m_triangles,
|
// triangulate the bed and store the triangles into m_bed.m_triangles,
|
||||||
@ -2093,6 +2103,31 @@ unsigned int Plater::priv::update_background_process(bool force_validation)
|
|||||||
// jinak background_process.running() -> Zobraz "Slicing ..."
|
// jinak background_process.running() -> Zobraz "Slicing ..."
|
||||||
// jinak pokud ! background_process.empty() && ! background_process.finished() -> je neco ke slajsovani (povol tlacitko) "Slice Now"
|
// jinak pokud ! background_process.empty() && ! background_process.finished() -> je neco ke slajsovani (povol tlacitko) "Slice Now"
|
||||||
|
|
||||||
|
if ((return_state & UPDATE_BACKGROUND_PROCESS_INVALID) != 0)
|
||||||
|
{
|
||||||
|
const wxString invalid_str = _(L("Invalid data"));
|
||||||
|
for (auto btn : {ActionButtonType::abReslice, ActionButtonType::abSendGCode, ActionButtonType::abExport})
|
||||||
|
sidebar->set_btn_label(btn, invalid_str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ||
|
||||||
|
(return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0 )
|
||||||
|
background_process.set_status("Ready to slice");
|
||||||
|
|
||||||
|
sidebar->set_btn_label(ActionButtonType::abExport, _(label_btn_export));
|
||||||
|
sidebar->set_btn_label(ActionButtonType::abSendGCode, _(L("Send G-code")));
|
||||||
|
|
||||||
|
const wxString slice_string = background_process.running() && wxGetApp().get_mode() == comSimple ?
|
||||||
|
_(L("Slicing")) + dots : _(L("Slice now"));
|
||||||
|
sidebar->set_btn_label(ActionButtonType::abReslice, slice_string);
|
||||||
|
|
||||||
|
if (background_process.finished())
|
||||||
|
show_action_buttons(false);
|
||||||
|
else if (!background_process.empty())
|
||||||
|
show_action_buttons(true);
|
||||||
|
}
|
||||||
|
|
||||||
return return_state;
|
return return_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2388,6 +2423,9 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
|
|||||||
this->update_sla_scene();
|
this->update_sla_scene();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wxGetApp().get_mode() == comSimple)
|
||||||
|
show_action_buttons(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::priv::on_layer_editing_toggled(bool enable)
|
void Plater::priv::on_layer_editing_toggled(bool enable)
|
||||||
@ -2755,6 +2793,37 @@ void Plater::priv::update_object_menu()
|
|||||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
|
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const
|
||||||
|
{
|
||||||
|
wxWindowUpdateLocker noUpdater(sidebar);
|
||||||
|
const auto prin_host_opt = config->option<ConfigOptionString>("print_host");
|
||||||
|
const bool send_gcode_shown = prin_host_opt != nullptr && !prin_host_opt->value.empty();
|
||||||
|
|
||||||
|
// when a background processing is ON, export_btn and/or send_btn are showing
|
||||||
|
if (wxGetApp().app_config->get("background_processing") == "1")
|
||||||
|
{
|
||||||
|
sidebar->show_reslice(false);
|
||||||
|
sidebar->show_export(true);
|
||||||
|
sidebar->show_send(send_gcode_shown);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sidebar->show_reslice(is_ready_to_slice);
|
||||||
|
sidebar->show_export(!is_ready_to_slice);
|
||||||
|
sidebar->show_send(send_gcode_shown && !is_ready_to_slice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& label) const
|
||||||
|
{
|
||||||
|
switch (btn_type)
|
||||||
|
{
|
||||||
|
case ActionButtonType::abReslice: p->btn_reslice->SetLabelText(label); break;
|
||||||
|
case ActionButtonType::abExport: p->btn_export_gcode->SetLabelText(label); break;
|
||||||
|
case ActionButtonType::abSendGCode: p->btn_send_gcode->SetLabelText(label); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Plater / Public
|
// Plater / Public
|
||||||
|
|
||||||
Plater::Plater(wxWindow *parent, MainFrame *main_frame)
|
Plater::Plater(wxWindow *parent, MainFrame *main_frame)
|
||||||
@ -3081,6 +3150,22 @@ void Plater::reslice()
|
|||||||
this->p->background_process.set_task(PrintBase::TaskParams());
|
this->p->background_process.set_task(PrintBase::TaskParams());
|
||||||
// Only restarts if the state is valid.
|
// Only restarts if the state is valid.
|
||||||
this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART);
|
this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART);
|
||||||
|
|
||||||
|
if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (p->background_process.running())
|
||||||
|
{
|
||||||
|
if (wxGetApp().get_mode() == comSimple)
|
||||||
|
p->sidebar->set_btn_label(ActionButtonType::abReslice, _(L("Slicing")) + dots);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->sidebar->set_btn_label(ActionButtonType::abReslice, _(L("Slice now")));
|
||||||
|
p->show_action_buttons(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!p->background_process.empty() && !p->background_process.idle())
|
||||||
|
p->show_action_buttons(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::reslice_SLA_supports(const ModelObject &object)
|
void Plater::reslice_SLA_supports(const ModelObject &object)
|
||||||
@ -3282,6 +3367,8 @@ void Plater::set_printer_technology(PrinterTechnology printer_technology)
|
|||||||
}
|
}
|
||||||
//FIXME for SLA synchronize
|
//FIXME for SLA synchronize
|
||||||
//p->background_process.apply(Model)!
|
//p->background_process.apply(Model)!
|
||||||
|
|
||||||
|
p->label_btn_export = printer_technology == ptFFF ? L("Export G-code") : L("Export"); // #ys_FIXME_rename
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::changed_object(int obj_idx)
|
void Plater::changed_object(int obj_idx)
|
||||||
|
@ -38,6 +38,7 @@ class GLCanvas3D;
|
|||||||
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
|
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
|
||||||
|
|
||||||
class Plater;
|
class Plater;
|
||||||
|
enum class ActionButtonType : int;
|
||||||
|
|
||||||
class PresetComboBox : public wxBitmapComboBox
|
class PresetComboBox : public wxBitmapComboBox
|
||||||
{
|
{
|
||||||
@ -86,8 +87,10 @@ public:
|
|||||||
void show_info_sizer();
|
void show_info_sizer();
|
||||||
void show_sliced_info_sizer(const bool show);
|
void show_sliced_info_sizer(const bool show);
|
||||||
void enable_buttons(bool enable);
|
void enable_buttons(bool enable);
|
||||||
void show_reslice(bool show);
|
void set_btn_label(const ActionButtonType btn_type, const wxString& label) const;
|
||||||
void show_send(bool show);
|
void show_reslice(bool show) const;
|
||||||
|
void show_export(bool show) const;
|
||||||
|
void show_send(bool show) const;
|
||||||
bool is_multifilament();
|
bool is_multifilament();
|
||||||
void set_mode_value(const /*ConfigOptionMode*/int mode) { m_mode = mode; }
|
void set_mode_value(const /*ConfigOptionMode*/int mode) { m_mode = mode; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user