Merge remote-tracking branch 'remotes/origin/ys_buttons'

This commit is contained in:
bubnikv 2019-03-12 09:01:17 +01:00
commit 1da97c9415
8 changed files with 192 additions and 46 deletions

View file

@ -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()

View file

@ -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();

View file

@ -3272,7 +3272,7 @@ bool GLCanvas3D::Gizmos::generate_icons_texture() const
} }
#endif // ENABLE_SVG_ICONS #endif // ENABLE_SVG_ICONS
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()
@ -3306,16 +3306,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();
@ -3332,7 +3339,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));
@ -3349,8 +3357,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);
@ -4579,23 +4588,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));
} }

View file

@ -794,7 +794,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,
@ -813,7 +814,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

View file

@ -534,20 +534,7 @@ void GUI_App::save_mode(const /*ConfigOptionMode*/int mode)
// Update view mode according to selected menu // Update view mode according to selected menu
void GUI_App::update_mode() void GUI_App::update_mode()
{ {
wxWindowUpdateLocker noUpdates(&sidebar()); sidebar().update_mode();
const ConfigOptionMode mode = wxGetApp().get_mode();
obj_list()->get_sizer()->Show(mode > comSimple);
sidebar().set_mode_value(mode);
// sidebar().show_buttons(mode == comExpert);
obj_list()->unselect_objects();
obj_list()->update_selections();
obj_list()->update_object_menu();
sidebar().update_mode_sizer(mode);
sidebar().Layout();
for (auto tab : tabs_list) for (auto tab : tabs_list)
tab->update_visibility(); tab->update_visibility();

View file

@ -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();

View file

@ -513,6 +513,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;
@ -675,7 +681,13 @@ Sidebar::Sidebar(Plater *parent)
// Events // Events
p->btn_export_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(); }); p->btn_export_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(); });
p->btn_reslice->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->reslice(); }); p->btn_reslice->Bind(wxEVT_BUTTON, [this](wxCommandEvent&)
{
const bool export_gcode_after_slicing = wxGetKeyState(WXK_SHIFT);
p->plater->reslice();
if (export_gcode_after_slicing)
p->plater->export_gcode();
});
p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); }); p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); });
} }
@ -773,9 +785,15 @@ void Sidebar::update_presets(Preset::Type preset_type)
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
} }
void Sidebar::update_mode_sizer(const Slic3r::ConfigOptionMode& mode) void Sidebar::update_mode_sizer() const
{ {
p->mode_sizer->SetMode(mode); p->mode_sizer->SetMode(m_mode);
}
void Sidebar::update_reslice_btn_tooltip() const
{
const wxString tooltip = m_mode == comSimple ? wxString("") : _(L("Hold Shift to Slice & Export G-code"));
p->btn_reslice->SetToolTip(tooltip);
} }
ObjectManipulation* Sidebar::obj_manipul() ObjectManipulation* Sidebar::obj_manipul()
@ -968,8 +986,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()
{ {
@ -977,6 +996,24 @@ bool Sidebar::is_multifilament()
} }
void Sidebar::update_mode()
{
m_mode = wxGetApp().get_mode();
update_reslice_btn_tooltip();
update_mode_sizer();
wxWindowUpdateLocker noUpdates(this);
p->object_list->get_sizer()->Show(m_mode > comSimple);
p->object_list->unselect_objects();
p->object_list->update_selections();
p->object_list->update_object_menu();
Layout();
}
std::vector<PresetComboBox*>& Sidebar::combos_filament() std::vector<PresetComboBox*>& Sidebar::combos_filament()
{ {
return p->combos_filament; return p->combos_filament;
@ -1060,6 +1097,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;
@ -1148,6 +1187,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,
@ -2118,6 +2158,35 @@ 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() &&
!background_process.running()) /* Do not update buttons if background process is running
* This condition is important for SLA mode especially,
* when this function is called several times during calculations
* */
show_action_buttons(true);
}
return return_state; return return_state;
} }
@ -2430,6 +2499,14 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
this->update_sla_scene(); this->update_sla_scene();
break; break;
} }
if (canceled) {
if (wxGetApp().get_mode() == comSimple)
sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now");
show_action_buttons(true);
}
else 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)
@ -2798,6 +2875,37 @@ void Plater::priv::update_object_menu()
view3D->update_toolbar_items_visibility(); view3D->update_toolbar_items_visibility();
} }
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)
@ -3124,6 +3232,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)
@ -3322,6 +3446,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)

View file

@ -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
{ {
@ -61,7 +62,7 @@ private:
class Sidebar : public wxPanel class Sidebar : public wxPanel
{ {
/*ConfigOptionMode*/int m_mode; ConfigOptionMode m_mode;
public: public:
Sidebar(Plater *parent); Sidebar(Plater *parent);
Sidebar(Sidebar &&) = delete; Sidebar(Sidebar &&) = delete;
@ -73,7 +74,8 @@ public:
void init_filament_combo(PresetComboBox **combo, const int extr_idx); void init_filament_combo(PresetComboBox **combo, const int extr_idx);
void remove_unused_filament_combos(const int current_extruder_count); void remove_unused_filament_combos(const int current_extruder_count);
void update_presets(Slic3r::Preset::Type preset_type); void update_presets(Slic3r::Preset::Type preset_type);
void update_mode_sizer(const Slic3r::ConfigOptionMode& mode); void update_mode_sizer() const;
void update_reslice_btn_tooltip() const;
ObjectManipulation* obj_manipul(); ObjectManipulation* obj_manipul();
ObjectList* obj_list(); ObjectList* obj_list();
@ -86,10 +88,12 @@ 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 update_mode();
std::vector<PresetComboBox*>& combos_filament(); std::vector<PresetComboBox*>& combos_filament();
private: private: