Merge branch 'master' into lm_sla_supports_auto

This commit is contained in:
Lukas Matena 2018-12-21 12:34:24 +01:00
commit 2ba28325f0
14 changed files with 196 additions and 38 deletions

View File

@ -44,6 +44,8 @@
#define ENABLE_RENDER_SELECTION_CENTER (0 && ENABLE_1_42_0) #define ENABLE_RENDER_SELECTION_CENTER (0 && ENABLE_1_42_0)
// Show visual hints in the 3D scene when sidebar matrix fields have focus // Show visual hints in the 3D scene when sidebar matrix fields have focus
#define ENABLE_SIDEBAR_VISUAL_HINTS (1 && ENABLE_1_42_0) #define ENABLE_SIDEBAR_VISUAL_HINTS (1 && ENABLE_1_42_0)
// Separate rendering for opaque and transparent volumes
#define ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING (1 && ENABLE_1_42_0)
#endif // _technologies_h_ #endif // _technologies_h_

View File

@ -797,6 +797,9 @@ int GLVolumeCollection::load_object_volume(
color[2] = 1.0f; color[2] = 1.0f;
} }
color[3] = model_volume->is_model_part() ? 1.f : 0.5f; */ color[3] = model_volume->is_model_part() ? 1.f : 0.5f; */
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
color[3] = model_volume->is_model_part() ? 1.f : 0.5f;
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
this->volumes.emplace_back(new GLVolume(color)); this->volumes.emplace_back(new GLVolume(color));
GLVolume &v = *this->volumes.back(); GLVolume &v = *this->volumes.back();
v.set_color_from_model_volume(model_volume); v.set_color_from_model_volume(model_volume);
@ -953,12 +956,54 @@ int GLVolumeCollection::load_wipe_tower_preview(
return int(this->volumes.size() - 1); return int(this->volumes.size() - 1);
} }
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
typedef std::pair<GLVolume*, double> GLVolumeWithZ;
typedef std::vector<GLVolumeWithZ> GLVolumesWithZList;
GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type)
{
GLVolumesWithZList list;
for (GLVolume* volume : volumes)
{
bool is_transparent = (volume->render_color[3] < 1.0f);
if (((type == GLVolumeCollection::Opaque) && !is_transparent) ||
((type == GLVolumeCollection::Transparent) && is_transparent) ||
(type == GLVolumeCollection::All))
list.push_back(std::make_pair(volume, 0.0));
}
if ((type == GLVolumeCollection::Transparent) && (list.size() > 1))
{
Transform3d modelview_matrix;
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
for (GLVolumeWithZ& volume : list)
{
volume.second = volume.first->bounding_box.transformed(modelview_matrix * volume.first->world_matrix()).max(2);
}
std::sort(list.begin(), list.end(),
[](const GLVolumeWithZ& v1, const GLVolumeWithZ& v2) -> bool { return v1.second < v2.second; }
);
}
return list;
}
void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface) const
#else
void GLVolumeCollection::render_VBOs() const void GLVolumeCollection::render_VBOs() const
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
{ {
::glEnable(GL_BLEND); ::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
::glCullFace(GL_BACK); ::glCullFace(GL_BACK);
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
if (disable_cullface)
::glDisable(GL_CULL_FACE);
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
::glEnableClientState(GL_VERTEX_ARRAY); ::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY); ::glEnableClientState(GL_NORMAL_ARRAY);
@ -980,6 +1025,18 @@ void GLVolumeCollection::render_VBOs() const
if (z_range_id != -1) if (z_range_id != -1)
::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range); ::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range);
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type);
for (GLVolumeWithZ& volume : to_render)
{
if (volume.first->layer_height_texture_data.can_use())
volume.first->generate_layer_height_texture(volume.first->layer_height_texture_data.print_object, false);
else
volume.first->set_render_color();
volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
}
#else
for (GLVolume *volume : this->volumes) for (GLVolume *volume : this->volumes)
{ {
if (volume->layer_height_texture_data.can_use()) if (volume->layer_height_texture_data.can_use())
@ -989,6 +1046,7 @@ void GLVolumeCollection::render_VBOs() const
volume->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id); volume->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
} }
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
::glBindBuffer(GL_ARRAY_BUFFER, 0); ::glBindBuffer(GL_ARRAY_BUFFER, 0);
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@ -996,27 +1054,55 @@ void GLVolumeCollection::render_VBOs() const
::glDisableClientState(GL_VERTEX_ARRAY); ::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY); ::glDisableClientState(GL_NORMAL_ARRAY);
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
if (disable_cullface)
::glEnable(GL_CULL_FACE);
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
::glDisable(GL_BLEND); ::glDisable(GL_BLEND);
} }
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface) const
#else
void GLVolumeCollection::render_legacy() const void GLVolumeCollection::render_legacy() const
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
{ {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_BACK); glCullFace(GL_BACK);
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
if (disable_cullface)
::glDisable(GL_CULL_FACE);
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type);
for (GLVolumeWithZ& volume : to_render)
{
volume.first->set_render_color();
volume.first->render_legacy();
}
#else
for (GLVolume *volume : this->volumes) for (GLVolume *volume : this->volumes)
{ {
volume->set_render_color(); volume->set_render_color();
volume->render_legacy(); volume->render_legacy();
} }
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
if (disable_cullface)
::glEnable(GL_CULL_FACE);
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }

View File

@ -500,6 +500,17 @@ typedef std::vector<GLVolume*> GLVolumePtrs;
class GLVolumeCollection class GLVolumeCollection
{ {
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
public:
enum ERenderType : unsigned char
{
Opaque,
Transparent,
All
};
private:
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
// min and max vertex of the print box volume // min and max vertex of the print box volume
float print_box_min[3]; float print_box_min[3];
float print_box_max[3]; float print_box_max[3];
@ -544,8 +555,13 @@ public:
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width); int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width);
// Render the volumes by OpenGL. // Render the volumes by OpenGL.
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
void render_VBOs(ERenderType type, bool disable_cullface) const;
void render_legacy(ERenderType type, bool disable_cullface) const;
#else
void render_VBOs() const; void render_VBOs() const;
void render_legacy() const; void render_legacy() const;
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
// Finalize the initialization of the geometry & indices, // Finalize the initialization of the geometry & indices,
// upload the geometry and indices to OpenGL VBO objects // upload the geometry and indices to OpenGL VBO objects

View File

@ -172,12 +172,14 @@ void Field::get_value_by_opt_type(wxString& str)
show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits"))); show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits")));
set_value(double_to_string(val), true); set_value(double_to_string(val), true);
} }
else if (val > 1) else if (m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max ||
m_opt.sidetext.rfind("mm ") != std::string::npos && val > 1)
{ {
std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm";
const int nVal = int(val); const int nVal = int(val);
wxString msg_text = wxString::Format(_(L("Do you mean %d%% instead of %dmm?\n" wxString msg_text = wxString::Format(_(L("Do you mean %d%% instead of %d %s?\n"
"Select YES if you want to change this value to %d%%, \n" "Select YES if you want to change this value to %d%%, \n"
"or NO if you are sure that %dmm is a correct value.")), nVal, nVal, nVal, nVal); "or NO if you are sure that %d %s is a correct value.")), nVal, nVal, sidetext, nVal, nVal, sidetext);
auto dialog = new wxMessageDialog(m_parent, msg_text, _(L("Parameter validation")), wxICON_WARNING | wxYES | wxNO); auto dialog = new wxMessageDialog(m_parent, msg_text, _(L("Parameter validation")), wxICON_WARNING | wxYES | wxNO);
if (dialog->ShowModal() == wxID_YES) { if (dialog->ShowModal() == wxID_YES) {
set_value(wxString::Format("%s%%", str), true); set_value(wxString::Format("%s%%", str), true);
@ -274,7 +276,6 @@ void TextCtrl::BUILD() {
e.Skip(); e.Skip();
temp->GetToolTip()->Enable(true); temp->GetToolTip()->Enable(true);
#endif // __WXGTK__ #endif // __WXGTK__
// if (!is_defined_input_value())
if (is_defined_input_value<wxTextCtrl>(window, m_opt.type)) if (is_defined_input_value<wxTextCtrl>(window, m_opt.type))
on_change_field(); on_change_field();
else else
@ -399,10 +400,11 @@ void SpinCtrl::BUILD() {
auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size,
0, min_val, max_val, default_value); 0, min_val, max_val, default_value);
// temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { tmp_value = undef_spin_val; on_change_field(); }), temp->GetId()); #ifndef __WXOSX__
// #ys_FIXME_KILL_FOCUS // #ys_FIXME_KILL_FOCUS
// wxEVT_KILL_FOCUS doesn't handled on OSX now // wxEVT_KILL_FOCUS doesn't handled on OSX now (wxWidgets 3.1.1)
// So, we will update values on KILL_FOCUS & SPINCTRL events under MSW and GTK
// and on TEXT event under OSX
temp->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) temp->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e)
{ {
if (tmp_value < 0) if (tmp_value < 0)
@ -413,6 +415,9 @@ void SpinCtrl::BUILD() {
} }
}), temp->GetId()); }), temp->GetId());
temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { on_change_field(); }), temp->GetId());
#endif
temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent e)
{ {
// # On OSX / Cocoa, wxSpinCtrl::GetValue() doesn't return the new value // # On OSX / Cocoa, wxSpinCtrl::GetValue() doesn't return the new value
@ -424,9 +429,7 @@ void SpinCtrl::BUILD() {
if (is_matched(value, "^\\d+$")) if (is_matched(value, "^\\d+$"))
tmp_value = std::stoi(value); tmp_value = std::stoi(value);
else tmp_value = -9999; else tmp_value = -9999;
// on_change_field();
#ifdef __WXOSX__ #ifdef __WXOSX__
// #ys_FIXME_KILL_FOCUS so call on_change_field() inside wxEVT_TEXT
if (tmp_value < 0) { if (tmp_value < 0) {
if (m_on_kill_focus != nullptr) if (m_on_kill_focus != nullptr)
m_on_kill_focus(m_opt_id); m_on_kill_focus(m_opt_id);

View File

@ -4313,7 +4313,13 @@ void GLCanvas3D::render()
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_render_background(); _render_background();
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
// textured bed needs to be rendered after objects if the texture is transparent
bool early_bed_render = is_custom_bed || (theta <= 90.0f);
if (early_bed_render)
#else
if (is_custom_bed) // untextured bed needs to be rendered before objects if (is_custom_bed) // untextured bed needs to be rendered before objects
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
_render_bed(theta); _render_bed(theta);
_render_objects(); _render_objects();
@ -4322,7 +4328,11 @@ void GLCanvas3D::render()
_render_axes(); _render_axes();
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
if (!early_bed_render)
#else
if (!is_custom_bed) // textured bed needs to be rendered after objects if (!is_custom_bed) // textured bed needs to be rendered after objects
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
_render_bed(theta); _render_bed(theta);
#if ENABLE_RENDER_SELECTION_CENTER #if ENABLE_RENDER_SELECTION_CENTER
@ -6119,7 +6129,7 @@ float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) co
// margin factor to give some empty space around the bbox // margin factor to give some empty space around the bbox
double margin_factor = 1.25; double margin_factor = 1.25;
for (const Vec3d v : vertices) for (const Vec3d& v : vertices)
{ {
// project vertex on the plane perpendicular to camera forward axis // project vertex on the plane perpendicular to camera forward axis
Vec3d pos(v(0) - bb_center(0), v(1) - bb_center(1), v(2) - bb_center(2)); Vec3d pos(v(0) - bb_center(0), v(1) - bb_center(1), v(2) - bb_center(2));
@ -6328,8 +6338,10 @@ void GLCanvas3D::_render_objects() const
m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height")); m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height"));
m_volumes.check_outside_state(m_config, nullptr); m_volumes.check_outside_state(m_config, nullptr);
} }
#if !ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
// do not cull backfaces to show broken geometry, if any // do not cull backfaces to show broken geometry, if any
::glDisable(GL_CULL_FACE); ::glDisable(GL_CULL_FACE);
#endif // !ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
} }
if (m_use_clipping_planes) if (m_use_clipping_planes)
@ -6338,11 +6350,19 @@ void GLCanvas3D::_render_objects() const
m_volumes.set_z_range(-FLT_MAX, FLT_MAX); m_volumes.set_z_range(-FLT_MAX, FLT_MAX);
m_shader.start_using(); m_shader.start_using();
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
// do not cull backfaces to show broken geometry, if any
m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled);
m_volumes.render_VBOs(GLVolumeCollection::Transparent, false);
#else
m_volumes.render_VBOs(); m_volumes.render_VBOs();
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
m_shader.stop_using(); m_shader.stop_using();
#if !ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
if (m_picking_enabled) if (m_picking_enabled)
::glEnable(GL_CULL_FACE); ::glEnable(GL_CULL_FACE);
#endif // !ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
} }
else else
{ {
@ -6354,14 +6374,24 @@ void GLCanvas3D::_render_objects() const
::glEnable(GL_CLIP_PLANE1); ::glEnable(GL_CLIP_PLANE1);
} }
#if !ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
// do not cull backfaces to show broken geometry, if any // do not cull backfaces to show broken geometry, if any
if (m_picking_enabled) if (m_picking_enabled)
::glDisable(GL_CULL_FACE); ::glDisable(GL_CULL_FACE);
#endif // !ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
// do not cull backfaces to show broken geometry, if any
m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled);
m_volumes.render_legacy(GLVolumeCollection::Transparent, false);
#else
m_volumes.render_legacy(); m_volumes.render_legacy();
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
#if !ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
if (m_picking_enabled) if (m_picking_enabled)
::glEnable(GL_CULL_FACE); ::glEnable(GL_CULL_FACE);
#endif // !ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
if (m_use_clipping_planes) if (m_use_clipping_planes)
{ {

View File

@ -554,6 +554,13 @@ ConfigMenuIDs GUI_App::get_view_mode()
mode == "simple" ? ConfigMenuModeSimple : ConfigMenuModeAdvanced; mode == "simple" ? ConfigMenuModeSimple : ConfigMenuModeAdvanced;
} }
ConfigOptionMode GUI_App::get_opt_mode() {
const ConfigMenuIDs mode = wxGetApp().get_view_mode();
return mode == ConfigMenuModeSimple ? comSimple :
mode == ConfigMenuModeExpert ? comExpert : comAdvanced;
}
// Update view mode according to selected menu // Update view mode according to selected menu
void GUI_App::update_mode() void GUI_App::update_mode()
{ {
@ -568,10 +575,8 @@ void GUI_App::update_mode()
sidebar().Layout(); sidebar().Layout();
ConfigOptionMode opt_mode = mode == ConfigMenuModeSimple ? comSimple :
mode == ConfigMenuModeExpert ? comExpert : comAdvanced;
for (auto tab : tabs_list) for (auto tab : tabs_list)
tab->update_visibility(opt_mode); tab->update_visibility();
plater()->update_object_menu(); plater()->update_object_menu();
} }

View File

@ -135,6 +135,7 @@ public:
Tab* get_tab(Preset::Type type); Tab* get_tab(Preset::Type type);
ConfigMenuIDs get_view_mode(); ConfigMenuIDs get_view_mode();
ConfigOptionMode get_opt_mode();
void update_mode(); void update_mode();
void add_config_menu(wxMenuBar *menu); void add_config_menu(wxMenuBar *menu);

View File

@ -99,7 +99,7 @@ void KBShortcutsDialog::fill_shortcuts()
main_shortcuts.reserve(25); main_shortcuts.reserve(25);
main_shortcuts.push_back(Shortcut(ctrl+"O" ,L("Open project STL/OBJ/AMF/3MF with config, delete bed"))); main_shortcuts.push_back(Shortcut(ctrl+"O" ,L("Open project STL/OBJ/AMF/3MF with config, delete bed")));
main_shortcuts.push_back(Shortcut(ctrl+"I" ,L("Import STL//OBJ/AMF/3MF without config, keep bed"))); main_shortcuts.push_back(Shortcut(ctrl+"I" ,L("Import STL/OBJ/AMF/3MF without config, keep bed")));
main_shortcuts.push_back(Shortcut(ctrl+"L" ,L("Load Config from .ini/amf/3mf/gcode"))); main_shortcuts.push_back(Shortcut(ctrl+"L" ,L("Load Config from .ini/amf/3mf/gcode")));
main_shortcuts.push_back(Shortcut(ctrl+"G" ,L("Export Gcode"))); main_shortcuts.push_back(Shortcut(ctrl+"G" ,L("Export Gcode")));
main_shortcuts.push_back(Shortcut(ctrl+"S" ,L("Save project (3MF)"))); main_shortcuts.push_back(Shortcut(ctrl+"S" ,L("Save project (3MF)")));

View File

@ -811,7 +811,7 @@ void MainFrame::on_value_changed(wxCommandEvent& event)
void MainFrame::update_ui_from_settings() void MainFrame::update_ui_from_settings()
{ {
bool bp_on = wxGetApp().app_config->get("background_processing") == "1"; 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().Layout(); m_plater->sidebar().Layout();
if (m_plater) if (m_plater)

View File

@ -224,7 +224,8 @@ PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
if (marker == LABEL_ITEM_MARKER) { if (marker == LABEL_ITEM_MARKER) {
this->SetSelection(this->last_selected); this->SetSelection(this->last_selected);
evt.StopPropagation(); evt.StopPropagation();
} else if (this->last_selected != selected_item) { } else if ( this->last_selected != selected_item ||
wxGetApp().get_tab(this->preset_type)->get_presets()->current_is_dirty() ) {
this->last_selected = selected_item; this->last_selected = selected_item;
evt.SetInt(this->preset_type); evt.SetInt(this->preset_type);
evt.Skip(); evt.Skip();
@ -945,6 +946,7 @@ struct Plater::priv
void select_view(const std::string& direction); void select_view(const std::string& direction);
#if ENABLE_REMOVE_TABS_FROM_PLATER #if ENABLE_REMOVE_TABS_FROM_PLATER
void select_view_3D(const std::string& name); void select_view_3D(const std::string& name);
void select_next_view_3D();
#endif // ENABLE_REMOVE_TABS_FROM_PLATER #endif // ENABLE_REMOVE_TABS_FROM_PLATER
void update_ui_from_settings(); void update_ui_from_settings();
ProgressStatusBar* statusbar(); ProgressStatusBar* statusbar();
@ -1118,8 +1120,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
view3D = new View3D(q, &model, config, &background_process); view3D = new View3D(q, &model, config, &background_process);
preview = new Preview(q, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); }); preview = new Preview(q, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); });
// Let the Tab key switch between the 3D view and the layer preview. // Let the Tab key switch between the 3D view and the layer preview.
view3D->Bind(wxEVT_NAVIGATION_KEY, [this](wxNavigationKeyEvent &evt) { if (evt.IsFromTab()) this->q->select_view_3D("Preview"); }); view3D->Bind(wxEVT_NAVIGATION_KEY, [this](wxNavigationKeyEvent &evt) { if (evt.IsFromTab()) this->select_next_view_3D(); });
preview->Bind(wxEVT_NAVIGATION_KEY, [this](wxNavigationKeyEvent &evt) { if (evt.IsFromTab()) this->q->select_view_3D("3D"); }); preview->Bind(wxEVT_NAVIGATION_KEY, [this](wxNavigationKeyEvent &evt) { if (evt.IsFromTab()) this->select_next_view_3D(); });
panels.push_back(view3D); panels.push_back(view3D);
panels.push_back(preview); panels.push_back(preview);
@ -1300,10 +1302,14 @@ void Plater::priv::select_view_3D(const std::string& name)
set_current_panel(view3D); set_current_panel(view3D);
else if (name == "Preview") else if (name == "Preview")
set_current_panel(preview); set_current_panel(preview);
}
#if !ENABLE_TOOLBAR_BACKGROUND_TEXTURE void Plater::priv::select_next_view_3D()
view_toolbar.set_selection(name); {
#endif // !ENABLE_TOOLBAR_BACKGROUND_TEXTURE if (current_panel == view3D)
set_current_panel(preview);
else if (current_panel == preview)
set_current_panel(view3D);
} }
#else #else
void Plater::priv::select_view(const std::string& direction) void Plater::priv::select_view(const std::string& direction)
@ -2243,13 +2249,17 @@ void Plater::priv::set_current_panel(wxPanel* panel)
} }
// sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably) // sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably)
view3D->set_as_dirty(); view3D->set_as_dirty();
view_toolbar.select_item("3D");
} }
else if (current_panel == preview) else if (current_panel == preview)
{ {
this->q->reslice(); this->q->reslice();
preview->reload_print(); preview->reload_print();
preview->set_canvas_as_dirty(); preview->set_canvas_as_dirty();
view_toolbar.select_item("Preview");
} }
current_panel->SetFocusFromKbd();
} }
#else #else
void Plater::priv::on_notebook_changed(wxBookCtrlEvent&) void Plater::priv::on_notebook_changed(wxBookCtrlEvent&)

View File

@ -667,8 +667,9 @@ void Tab::reload_config()
Thaw(); Thaw();
} }
void Tab::update_visibility(ConfigOptionMode mode) void Tab::update_visibility()
{ {
const ConfigOptionMode mode = wxGetApp().get_opt_mode();
Freeze(); Freeze();
for (auto page : m_pages) for (auto page : m_pages)
@ -1988,6 +1989,7 @@ PageShp TabPrinter::build_kinematics_page()
def.type = coString; def.type = coString;
def.width = 150; def.width = 150;
def.gui_type = "legend"; def.gui_type = "legend";
def.mode = comAdvanced;
def.tooltip = L("Values in this column are for Full Power mode"); def.tooltip = L("Values in this column are for Full Power mode");
def.default_value = new ConfigOptionString{ L("Full Power") }; def.default_value = new ConfigOptionString{ L("Full Power") };
@ -2345,12 +2347,15 @@ void Tab::load_current_preset()
init_options_list(); init_options_list();
update_changed_ui(); update_changed_ui();
}); });
update_page_tree_visibility();
} }
//Regerenerate content of the page tree. //Regerenerate content of the page tree.
void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/) void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/)
{ {
Freeze(); Freeze();
update_visibility();
// get label of the currently selected item // get label of the currently selected item
const auto sel_item = m_treectrl->GetSelection(); const auto sel_item = m_treectrl->GetSelection();
const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : ""; const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : "";
@ -2363,8 +2368,8 @@ void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/)
auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID()); auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID());
m_treectrl->SetItemTextColour(itemId, p->get_item_colour()); m_treectrl->SetItemTextColour(itemId, p->get_item_colour());
if (p->title() == selected) { if (p->title() == selected) {
if (!(p->title() == _(L("Machine limits")) || p->title() == _(L("Single extruder MM setup")))) // These Pages have to be updated inside OnTreeSelChange // if (!(p->title() == _(L("Machine limits")) || p->title() == _(L("Single extruder MM setup")))) // These Pages have to be updated inside OnTreeSelChange
m_disable_tree_sel_changed_event = !tree_sel_change_event; // m_disable_tree_sel_changed_event = !tree_sel_change_event;
m_treectrl->SelectItem(itemId); m_treectrl->SelectItem(itemId);
m_disable_tree_sel_changed_event = false; m_disable_tree_sel_changed_event = false;
have_selection = 1; have_selection = 1;
@ -2924,14 +2929,15 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
auto extra_column = [](wxWindow* parent, const Line& line) auto extra_column = [](wxWindow* parent, const Line& line)
{ {
std::string bmp_name; std::string bmp_name;
if (line.get_options().size() == 0) const std::vector<Option>& options = line.get_options();
bmp_name = "error.png"; if (options.size() == 0 || options[0].opt.gui_type == "legend")
bmp_name = "";// "error.png";
else { else {
auto mode = line.get_options()[0].opt.mode; //we assume that we have one option per line auto mode = options[0].opt.mode; //we assume that we have one option per line
bmp_name = mode == comExpert ? "mode_expert_.png" : bmp_name = mode == comExpert ? "mode_expert_.png" :
mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png"; mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png";
} }
auto bmp = new wxStaticBitmap(parent, wxID_ANY, wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG)); auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG));
return bmp; return bmp;
}; };

View File

@ -257,7 +257,7 @@ public:
void update_tab_ui(); void update_tab_ui();
void load_config(const DynamicPrintConfig& config); void load_config(const DynamicPrintConfig& config);
virtual void reload_config(); virtual void reload_config();
void update_visibility(ConfigOptionMode mode); void update_visibility();
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
bool set_value(const t_config_option_key& opt_key, const boost::any& value); bool set_value(const t_config_option_key& opt_key, const boost::any& value);
wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText); wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText);

View File

@ -32,7 +32,7 @@ class CurlGlobalInit
struct Http::priv struct Http::priv
{ {
enum { enum {
DEFAULT_TIMEOUT = 10, DEFAULT_TIMEOUT_CONNECT = 10,
DEFAULT_SIZE_LIMIT = 5 * 1024 * 1024, DEFAULT_SIZE_LIMIT = 5 * 1024 * 1024,
}; };
@ -64,7 +64,7 @@ struct Http::priv
static int xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow); static int xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow);
static size_t form_file_read_cb(char *buffer, size_t size, size_t nitems, void *userp); static size_t form_file_read_cb(char *buffer, size_t size, size_t nitems, void *userp);
void set_timeout(long timeout); void set_timeout_connect(long timeout);
void form_add_file(const char *name, const fs::path &path, const char* filename); void form_add_file(const char *name, const fs::path &path, const char* filename);
void set_post_body(const fs::path &path); void set_post_body(const fs::path &path);
@ -86,7 +86,7 @@ Http::priv::priv(const std::string &url)
throw std::runtime_error(std::string("Could not construct Curl object")); throw std::runtime_error(std::string("Could not construct Curl object"));
} }
set_timeout(DEFAULT_TIMEOUT); set_timeout_connect(DEFAULT_TIMEOUT_CONNECT);
::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // curl makes a copy internally ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // curl makes a copy internally
::curl_easy_setopt(curl, CURLOPT_USERAGENT, SLIC3R_FORK_NAME "/" SLIC3R_VERSION); ::curl_easy_setopt(curl, CURLOPT_USERAGENT, SLIC3R_FORK_NAME "/" SLIC3R_VERSION);
::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer.front()); ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer.front());
@ -172,10 +172,9 @@ size_t Http::priv::form_file_read_cb(char *buffer, size_t size, size_t nitems, v
return stream->gcount(); return stream->gcount();
} }
void Http::priv::set_timeout(long timeout) void Http::priv::set_timeout_connect(long timeout)
{ {
::curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout); ::curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
} }
void Http::priv::form_add_file(const char *name, const fs::path &path, const char* filename) void Http::priv::form_add_file(const char *name, const fs::path &path, const char* filename)
@ -306,10 +305,10 @@ Http::~Http()
} }
Http& Http::timeout(long timeout) Http& Http::timeout_connect(long timeout)
{ {
if (timeout < 1) { timeout = priv::DEFAULT_TIMEOUT; } if (timeout < 1) { timeout = priv::DEFAULT_TIMEOUT_CONNECT; }
if (p) { p->set_timeout(timeout); } if (p) { p->set_timeout_connect(timeout); }
return *this; return *this;
} }

View File

@ -56,7 +56,7 @@ public:
Http& operator=(Http &&) = delete; Http& operator=(Http &&) = delete;
// Sets a maximum connection timeout in seconds // Sets a maximum connection timeout in seconds
Http& timeout(long timeout); Http& timeout_connect(long timeout);
// Sets a maximum size of the data that can be received. // Sets a maximum size of the data that can be received.
// A value of zero sets the default limit, which is is 5MB. // A value of zero sets the default limit, which is is 5MB.
Http& size_limit(size_t sizeLimit); Http& size_limit(size_t sizeLimit);