From c973500ee65c92dc99b7a8177c75604f2966bc4c Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 29 Jan 2019 10:21:21 +0100 Subject: [PATCH 01/28] Support for a numeric input with both dot and comma as a valid decimal separator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes Česká verze hustota filamentu #1705 --- src/slic3r/GUI/Field.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 3dd160432..862f1b107 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -143,9 +143,11 @@ void Field::get_value_by_opt_type(wxString& str) break; } double val; + // Replace the first occurence of comma in decimal number. + str.Replace(",", ".", false); if(!str.ToCDouble(&val)) { - show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits"))); + show_error(m_parent, _(L("Invalid numeric input."))); set_value(double_to_string(val), true); } if (m_opt.min > val || val > m_opt.max) @@ -163,10 +165,12 @@ void Field::get_value_by_opt_type(wxString& str) if (m_opt.type == coFloatOrPercent && !str.IsEmpty() && str.Last() != '%') { double val; + // Replace the first occurence of comma in decimal number. + str.Replace(",", ".", false); if (!str.ToCDouble(&val)) { - show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits"))); - set_value(double_to_string(val), true); + show_error(m_parent, _(L("Invalid numeric input."))); + set_value(double_to_string(val), true); } 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) @@ -334,6 +338,7 @@ void TextCtrl::propagate_value() boost::any& TextCtrl::get_value() { wxString ret_str = static_cast(window)->GetValue(); + // modifies ret_string! get_value_by_opt_type(ret_str); return m_value; @@ -727,11 +732,13 @@ boost::any& Choice::get_value() else if (m_opt.gui_type == "f_enum_open") { const int ret_enum = static_cast(window)->GetSelection(); if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings) + // modifies ret_string! get_value_by_opt_type(ret_str); else m_value = atof(m_opt.enum_values[ret_enum].c_str()); } else + // modifies ret_string! get_value_by_opt_type(ret_str); return m_value; From de742bbab2a81ee182fc707754227dcbdbfa5869 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 29 Jan 2019 11:14:29 +0100 Subject: [PATCH 02/28] Fix of Custom filename - used_filament in meters #1680 --- src/libslic3r/Print.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 1ef6c7b84..ea2d9b03d 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1908,7 +1908,7 @@ DynamicConfig PrintStatistics::config() const config.set_key_value("print_time", new ConfigOptionString(normal_print_time)); config.set_key_value("normal_print_time", new ConfigOptionString(normal_print_time)); config.set_key_value("silent_print_time", new ConfigOptionString(silent_print_time)); - config.set_key_value("used_filament", new ConfigOptionFloat (this->total_used_filament)); + config.set_key_value("used_filament", new ConfigOptionFloat (this->total_used_filament / 1000.)); config.set_key_value("extruded_volume", new ConfigOptionFloat (this->total_extruded_volume)); config.set_key_value("total_cost", new ConfigOptionFloat (this->total_cost)); config.set_key_value("total_weight", new ConfigOptionFloat (this->total_weight)); @@ -1924,7 +1924,7 @@ DynamicConfig PrintStatistics::placeholders() "print_time", "normal_print_time", "silent_print_time", "used_filament", "extruded_volume", "total_cost", "total_weight", "total_wipe_tower_cost", "total_wipe_tower_filament"}) - config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}")); + config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}")); return config; } From aaaffd7f90d843d585e624a39ea24fe73c9d9ac1 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 29 Jan 2019 12:02:48 +0100 Subject: [PATCH 03/28] Fixes Add [layer_num] and [layer_z] to Custom Tool change G-code #1651 --- src/libslic3r/GCode.cpp | 10 +++++----- src/libslic3r/GCode.hpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 67264b16f..2a53e0444 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -860,7 +860,7 @@ void GCode::_do_export(Print &print, FILE *file) if (! (has_wipe_tower && print.config().single_extruder_multi_material_priming)) { // Set initial extruder only after custom start G-code. // Ugly hack: Do not set the initial extruder if the extruder is primed using the MMU priming towers at the edge of the print bed. - _write(file, this->set_extruder(initial_extruder_id)); + _write(file, this->set_extruder(initial_extruder_id, 0.)); } // Do all objects for each layer. @@ -1533,15 +1533,13 @@ void GCode::process_layer( } } // for objects - - // Extrude the skirt, brim, support, perimeters, infill ordered by the extruders. std::vector> lower_layer_edge_grids(layers.size()); for (unsigned int extruder_id : layer_tools.extruders) { gcode += (layer_tools.has_wipe_tower && m_wipe_tower) ? m_wipe_tower->tool_change(*this, extruder_id, extruder_id == layer_tools.extruders.back()) : - this->set_extruder(extruder_id); + this->set_extruder(extruder_id, print_z); // let analyzer tag generator aware of a role type change if (m_enable_analyzer && layer_tools.has_wipe_tower && m_wipe_tower) @@ -2643,7 +2641,7 @@ std::string GCode::retract(bool toolchange) return gcode; } -std::string GCode::set_extruder(unsigned int extruder_id) +std::string GCode::set_extruder(unsigned int extruder_id, double print_z) { if (!m_writer.need_toolchange(extruder_id)) return ""; @@ -2677,6 +2675,8 @@ std::string GCode::set_extruder(unsigned int extruder_id) DynamicConfig config; config.set_key_value("previous_extruder", new ConfigOptionInt((int)m_writer.extruder()->id())); config.set_key_value("next_extruder", new ConfigOptionInt((int)extruder_id)); + config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); + config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); gcode += placeholder_parser_process("toolchange_gcode", m_config.toolchange_gcode.value, extruder_id, &config); check_add_eol(gcode); } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 86a6cacee..faa6384cd 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -257,12 +257,12 @@ protected: bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone); std::string retract(bool toolchange = false); std::string unretract() { return m_writer.unlift() + m_writer.unretract(); } - std::string set_extruder(unsigned int extruder_id); + std::string set_extruder(unsigned int extruder_id, double print_z); /* Origin of print coordinates expressed in unscaled G-code coordinates. This affects the input arguments supplied to the extrude*() and travel_to() methods. */ - Vec2d m_origin; + Vec2d m_origin; FullPrintConfig m_config; GCodeWriter m_writer; PlaceholderParser m_placeholder_parser; From b47355a325800d4418a4b924637cc95253f58a71 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Jan 2019 12:05:49 +0100 Subject: [PATCH 04/28] Added limit to zoom in --- src/slic3r/GUI/GLCanvas3D.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7366516d1..5828c0e89 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5951,6 +5951,9 @@ void GLCanvas3D::set_camera_zoom(float zoom) if (zoom_min > 0.0f) zoom = std::max(zoom, zoom_min * 0.7f); + // Don't allow to zoom too close to the scene. + zoom = std::min(zoom, 100.0f); + m_camera.zoom = zoom; viewport_changed(); _refresh_if_shown_on_screen(); From e35124b627b6206ba457fdfc632f2d0ac7b3553d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 29 Jan 2019 13:36:23 +0100 Subject: [PATCH 05/28] Fix of 1.42.0.alpha2 BUG ** Printer choosing bug #1588 --- src/slic3r/GUI/Preset.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index d4ee9cf5f..f0473b823 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -531,6 +531,9 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri boost::filesystem::path dir = boost::filesystem::canonical(boost::filesystem::path(dir_path) / subdir).make_preferred(); m_dir_path = dir.string(); std::string errors_cummulative; + // Store the loaded presets into a new vector, otherwise the binary search for already existing presets would be broken. + // (see the "Preset already present, not loading" message). + std::deque presets_loaded; for (auto &dir_entry : boost::filesystem::directory_iterator(dir)) if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini") && // Ignore system and hidden files, which may be created by the DropBox synchronisation process. @@ -568,12 +571,13 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri } catch (const std::runtime_error &err) { throw std::runtime_error(std::string("Failed loading the preset file: ") + preset.file + "\n\tReason: " + err.what()); } - m_presets.emplace_back(preset); + presets_loaded.emplace_back(preset); } catch (const std::runtime_error &err) { errors_cummulative += err.what(); errors_cummulative += "\n"; } } + m_presets.insert(m_presets.end(), std::make_move_iterator(presets_loaded.begin()), std::make_move_iterator(presets_loaded.end())); std::sort(m_presets.begin() + m_num_default_presets, m_presets.end()); this->select_preset(first_visible_idx()); if (! errors_cummulative.empty()) From 15b6b4f2394e417ea3ba38d6a1aa4a915197ef3a Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Jan 2019 14:16:31 +0100 Subject: [PATCH 06/28] Fix of #1730 --- src/libslic3r/Model.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index d86a180b8..86bd0d03b 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -489,6 +489,9 @@ void Model::convert_multipart_object(unsigned int max_extruders) { new_v->name = o->name; new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string(max_extruders)); +#if ENABLE_VOLUMES_CENTERING_FIXES + new_v->translate(-o->origin_translation); +#endif // ENABLE_VOLUMES_CENTERING_FIXES } } From 2c9a98b22fa2b1cf2d0dbf470e20a91095a2651a Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 29 Jan 2019 14:44:10 +0100 Subject: [PATCH 07/28] Renamed Open / Save to Open Project / Save Project --- src/slic3r/GUI/MainFrame.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 2df3429fe..51f1c5f19 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -236,11 +236,11 @@ void MainFrame::init_menubar() // File menu wxMenu* fileMenu = new wxMenu; { - wxMenuItem* item_open = append_menu_item(fileMenu, wxID_ANY, _(L("&Open")) + dots + "\tCtrl+O", _(L("Open a project file")), + wxMenuItem* item_open = append_menu_item(fileMenu, wxID_ANY, _(L("&Open Project")) + dots + "\tCtrl+O", _(L("Open a project file")), [this](wxCommandEvent&) { if (m_plater) m_plater->load_project(); }, "brick_add.png"); - wxMenuItem* item_save = append_menu_item(fileMenu, wxID_ANY, _(L("&Save")) + "\tCtrl+S", _(L("Save current project file")), + wxMenuItem* item_save = append_menu_item(fileMenu, wxID_ANY, _(L("&Save Project")) + "\tCtrl+S", _(L("Save current project file")), [this](wxCommandEvent&) { if (m_plater) m_plater->export_3mf(into_path(m_plater->get_project_filename())); }, "disk.png"); - wxMenuItem* item_save_as = append_menu_item(fileMenu, wxID_ANY, _(L("Save &as")) + dots + "\tCtrl+Alt+S", _(L("Save current project file as")), + wxMenuItem* item_save_as = append_menu_item(fileMenu, wxID_ANY, _(L("Save Project &as")) + dots + "\tCtrl+Alt+S", _(L("Save current project file as")), [this](wxCommandEvent&) { if (m_plater) m_plater->export_3mf(); }, "disk.png"); fileMenu->AppendSeparator(); From e291172e2462633b686adf1b217fcaa8da54de97 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 29 Jan 2019 15:11:29 +0100 Subject: [PATCH 08/28] Implemented "Color Print" for preview mode (without re-slicing) --- src/libslic3r/GCode/PreviewData.cpp | 23 ++++++--- src/libslic3r/GCode/PreviewData.hpp | 2 + src/slic3r/GUI/GLCanvas3D.cpp | 80 +++++++++++++++++++++++------ src/slic3r/GUI/GLCanvas3D.hpp | 8 +-- src/slic3r/GUI/GUI_Preview.cpp | 18 +++++-- src/slic3r/GUI/wxExtensions.cpp | 2 +- 6 files changed, 102 insertions(+), 31 deletions(-) diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index e99eeac02..cd6be3db1 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -479,14 +479,17 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: } case Extrusion::ColorPrint: { - const auto color_print_cnt = cp_values.size(); - for (int i = color_print_cnt; i >= 0 ; --i) - { - int val = i; - while (val >= GCodePreviewData::Range::Colors_Count) - val -= GCodePreviewData::Range::Colors_Count; - GCodePreviewData::Color color = Range::Default_Colors[val]; + const size_t color_cnt = tool_colors.size()/4; + const auto color_print_cnt = cp_values.size(); + for (size_t i = color_print_cnt; i >= 0 ; --i) + { + size_t val = i; + while (val >= color_cnt) + val -= color_cnt; + GCodePreviewData::Color color; + ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + val * 4), 4 * sizeof(float)); + if (color_print_cnt == 0) { items.emplace_back(Slic3r::I18N::translate(L("Default print color")), color); break; @@ -521,6 +524,12 @@ size_t GCodePreviewData::memory_used() const sizeof(shell) + sizeof(ranges); } +const std::vector& GCodePreviewData::ColorPrintColors() +{ + static std::vector color_print = {"#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6"}; + return color_print; +} + GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2) { return GCodePreviewData::Color(clamp(0.0f, 1.0f, c1.rgba[0] + c2.rgba[0]), diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 4ca579d9a..e934dc80a 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -216,6 +216,8 @@ public: // Return an estimate of the memory consumed by the time estimator. size_t memory_used() const; + + static const std::vector& ColorPrintColors(); }; GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7366516d1..97462ef86 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3742,14 +3742,9 @@ GLCanvas3D::LegendTexture::LegendTexture() { } -bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector& tool_colors, const GLCanvas3D& canvas, bool use_error_colors) +void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, + std::vector>& cp_legend_values) { - reset(); - - // collects items to render - auto title = _(preview_data.get_legend_title()); - - std::vector> cp_legend_values; if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) { const auto& config = wxGetApp().preset_bundle->full_config(); @@ -3773,7 +3768,19 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c } } } - const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, /*color_print_values*/cp_legend_values); +} + +bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector& tool_colors, const GLCanvas3D& canvas, bool use_error_colors) +{ + reset(); + + // collects items to render + auto title = _(preview_data.get_legend_title()); + + std::vector> cp_legend_values; + fill_color_print_legend_values(preview_data, canvas, cp_legend_values); + + const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_values); unsigned int items_count = (unsigned int)items.size(); if (items_count == 0) @@ -4961,7 +4968,7 @@ void GLCanvas3D::load_sla_preview() } } -void GLCanvas3D::load_preview(const std::vector& str_tool_colors) +void GLCanvas3D::load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values) { const Print *print = this->fff_print(); if (print == nullptr) @@ -4972,7 +4979,7 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors) for (const PrintObject* object : print->objects()) { if (object != nullptr) - _load_print_object_toolpaths(*object, str_tool_colors); + _load_print_object_toolpaths(*object, str_tool_colors, color_print_values); } for (GLVolume* volume : m_volumes.volumes) @@ -4982,7 +4989,14 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors) _update_toolpath_volumes_outside_state(); _show_warning_texture_if_needed(); - reset_legend_texture(); + if (color_print_values.empty()) + reset_legend_texture(); + else { + auto preview_data = GCodePreviewData(); + preview_data.extrusion.view_type = GCodePreviewData::Extrusion::ColorPrint; + const std::vector tool_colors = _parse_colors(str_tool_colors); + _generate_legend_texture(preview_data, tool_colors); + } } void GLCanvas3D::bind_event_handlers() @@ -7235,7 +7249,7 @@ void GLCanvas3D::_load_print_toolpaths() volume.indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); } -void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors) +void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) { std::vector tool_colors = _parse_colors(str_tool_colors); @@ -7247,6 +7261,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c bool has_infill; bool has_support; const std::vector* tool_colors; + const std::vector* color_print_values; // Number of vertices (each vertex is 6x4=24 bytes long) static const size_t alloc_size_max() { return 131072; } // 3.15MB @@ -7266,12 +7281,37 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c { return this->color_by_tool() ? std::min(this->number_tools() - 1, std::max(extruder - 1, 0)) : feature; } + + // For coloring by a color_print(M600), return a parsed color. + bool color_by_color_print() const { return color_print_values!=nullptr; } + const float* color_print_by_layer_idx(const size_t layer_idx) const + { + double z = layers[layer_idx]->print_z; + size_t layer = 0; + const size_t clr_change_cnt = color_print_values->size(); + for (size_t i = 0; i < clr_change_cnt; i++) + { + if (z < (*color_print_values)[i]-EPSILON) { + layer = i; + break; + } + if (layer == 0 && i == clr_change_cnt - 1) + layer = clr_change_cnt; + } + + const size_t clr_cnt = number_tools(); + while (layer >= clr_cnt) + layer -= clr_cnt; + + return color_tool(layer); + } } ctxt; ctxt.has_perimeters = print_object.is_step_done(posPerimeters); ctxt.has_infill = print_object.is_step_done(posInfill); ctxt.has_support = print_object.is_step_done(posSupportMaterial); ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors; + ctxt.color_print_values = color_print_values.empty() ? nullptr : &color_print_values; ctxt.shifted_copies = &print_object.copies(); @@ -7296,7 +7336,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start"; //FIXME Improve the heuristics for a grain size. - size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1)); + size_t grain_size = ctxt.color_by_color_print() ? size_t(1) : std::max(ctxt.layers.size() / 16, size_t(1)); tbb::spin_mutex new_volume_mutex; auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* { auto *volume = new GLVolume(color); @@ -7311,7 +7351,9 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c tbb::blocked_range(0, ctxt.layers.size(), grain_size), [&ctxt, &new_volume](const tbb::blocked_range& range) { GLVolumePtrs vols; - if (ctxt.color_by_tool()) { + if (ctxt.color_by_color_print()) + vols.emplace_back(new_volume(ctxt.color_print_by_layer_idx(range.begin()))); + else if (ctxt.color_by_tool()) { for (size_t i = 0; i < ctxt.number_tools(); ++i) vols.emplace_back(new_volume(ctxt.color_tool(i))); } @@ -7629,11 +7671,15 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat } case GCodePreviewData::Extrusion::ColorPrint: { + const size_t color_cnt = tool_colors.size() / 4; + int val = int(value); - while (val >= GCodePreviewData::Range::Colors_Count) - val -= GCodePreviewData::Range::Colors_Count; + while (val >= color_cnt) + val -= color_cnt; - GCodePreviewData::Color color = GCodePreviewData::Range::Default_Colors[val]; + GCodePreviewData::Color color; + ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + val * 4), 4 * sizeof(float)); + return color; } default: diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8bdbf89b0..7d38e5128 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -857,6 +857,8 @@ private: public: LegendTexture(); + void fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, + std::vector>& cp_legend_values); bool generate(const GCodePreviewData& preview_data, const std::vector& tool_colors, const GLCanvas3D& canvas, bool use_error_colors); @@ -1027,8 +1029,7 @@ public: void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); void load_sla_preview(); - void load_preview(const std::vector& str_tool_colors); - + void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); void bind_event_handlers(); void unbind_event_handlers(); @@ -1133,7 +1134,8 @@ private: // Create 3D thick extrusion lines for object forming extrusions. // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes, // one for perimeters, one for infill and one for supports. - void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors); + void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, + const std::vector& color_print_values); // Create 3D thick extrusion lines for wipe tower extrusions void _load_wipe_tower_toolpaths(const std::vector& str_tool_colors); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 53ca52cb6..eb35aa61e 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -558,6 +558,7 @@ void Preview::create_double_slider() m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; m_preferred_color_mode = "feature"; } + reload_print(); }); } @@ -728,10 +729,19 @@ void Preview::load_print_as_fff() m_preferred_color_mode = "tool_or_feature"; } + bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); // Collect colors per extruder. std::vector colors; - bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); - if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool)) + std::vector color_print_values = {}; + // set color print values, if it si selected "ColorPrint" view type + if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) + { + colors = GCodePreviewData::ColorPrintColors(); + + const auto& config = wxGetApp().preset_bundle->full_config(); + color_print_values = config.option("colorprint_heights")->values; + } + else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) { const ConfigOptionStrings* extruders_opt = dynamic_cast(m_config->option("extruder_colour")); const ConfigOptionStrings* filamemts_opt = dynamic_cast(m_config->option("filament_colour")); @@ -750,6 +760,8 @@ void Preview::load_print_as_fff() colors.push_back(color); } + if (!color_print_values.empty()) + color_print_values.clear(); } if (IsShown()) @@ -759,7 +771,7 @@ void Preview::load_print_as_fff() m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); else // Load the initial preview based on slices, not the final G-code. - m_canvas->load_preview(colors); + m_canvas->load_preview(colors, color_print_values); show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); // recalculates zs and update sliders accordingly std::vector zs = m_canvas->get_current_print_zs(true); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 827dcc696..238a36c74 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1668,7 +1668,7 @@ void PrusaDoubleSlider::render() // draw colored band on the background of a scroll line // and only in a case of no-empty m_values - draw_colored_band(dc); +// draw_colored_band(dc); // draw line draw_scroll_line(dc, lower_pos, higher_pos); From ed71f2ccd72f1ad864ec3c6c7a5e18ac9d6aa6bf Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Jan 2019 16:11:53 +0100 Subject: [PATCH 09/28] Fix of #1713 --- src/slic3r/GUI/GLCanvas3D.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5828c0e89..128a21966 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3250,6 +3250,7 @@ bool GLCanvas3D::Gizmos::handle_shortcut(int key, const Selection& selection) if (!m_enabled || selection.is_empty()) return false; + EType old_current = m_current; bool handled = false; for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { @@ -3273,7 +3274,12 @@ bool GLCanvas3D::Gizmos::handle_shortcut(int key, const Selection& selection) handled = true; } } - else + } + + if (handled && (old_current != Undefined) && (old_current != m_current)) + { + GizmosMap::const_iterator it = m_gizmos.find(old_current); + if (it != m_gizmos.end()) it->second->set_state(GLGizmoBase::Off); } From a99c82340100847e56fa712f4a60c927ce4a3500 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Tue, 29 Jan 2019 15:48:30 +0100 Subject: [PATCH 10/28] Build: MSVC 2017 compat (w/o xs code - Perl unit tests) --- deps/deps-windows.cmake | 23 ++++++++++++++++++----- src/avrdude/windows/unistd.h | 2 ++ src/libslic3r/Int128.hpp | 5 +++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 44a1843bb..7276277e6 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -1,8 +1,21 @@ +if (MSVC_VERSION EQUAL 1800) + set(DEP_VS_VER "12") + set(DEP_BOOST_TOOLSET "msvc-12.0") +elseif (MSVC_VERSION EQUAL 1900) + set(DEP_VS_VER "14") + set(DEP_BOOST_TOOLSET "msvc-14.0") +elseif (MSVC_VERSION GREATER 1900) + set(DEP_VS_VER "15") + set(DEP_BOOST_TOOLSET "msvc-14.1") +else () + message(FATAL_ERROR "Unsupported MSVC version") +endif () + if (${DEPS_BITS} EQUAL 32) - set(DEP_MSVC_GEN "Visual Studio 12") + set(DEP_MSVC_GEN "Visual Studio ${DEP_VS_VER}") else () - set(DEP_MSVC_GEN "Visual Studio 12 Win64") + set(DEP_MSVC_GEN "Visual Studio ${DEP_VS_VER} Win64") endif () @@ -29,7 +42,7 @@ ExternalProject_Add(dep_boost --with-regex "--prefix=${DESTDIR}/usr/local" "address-model=${DEPS_BITS}" - toolset=msvc-12.0 + "toolset=${DEP_BOOST_TOOLSET}" link=static variant=release threading=multi @@ -204,7 +217,7 @@ ExternalProject_Add(dep_libcurl URL_HASH SHA256=cc245bf9a1a42a45df491501d97d5593392a03f7b4f07b952793518d97666115 BUILD_IN_SOURCE 1 CONFIGURE_COMMAND "" - BUILD_COMMAND cd winbuild && nmake /f Makefile.vc mode=static VC=12 GEN_PDB=yes DEBUG=no "MACHINE=${DEP_LIBCURL_TARGET}" + BUILD_COMMAND cd winbuild && nmake /f Makefile.vc mode=static "VC=${DEP_VS_VER}" GEN_PDB=yes DEBUG=no "MACHINE=${DEP_LIBCURL_TARGET}" INSTALL_COMMAND cd builds\\libcurl-*-release-*-winssl && "${CMAKE_COMMAND}" -E copy_directory include "${DESTDIR}\\usr\\local\\include" && "${CMAKE_COMMAND}" -E copy_directory lib "${DESTDIR}\\usr\\local\\lib" @@ -214,7 +227,7 @@ if (${DEP_DEBUG}) ExternalProject_Add_Step(dep_libcurl build_debug DEPENDEES build DEPENDERS install - COMMAND cd winbuild && nmake /f Makefile.vc mode=static VC=12 GEN_PDB=yes DEBUG=yes "MACHINE=${DEP_LIBCURL_TARGET}" + COMMAND cd winbuild && nmake /f Makefile.vc mode=static "VC=${DEP_VS_VER}" GEN_PDB=yes DEBUG=yes "MACHINE=${DEP_LIBCURL_TARGET}" WORKING_DIRECTORY "${SOURCE_DIR}" ) ExternalProject_Add_Step(dep_libcurl install_debug diff --git a/src/avrdude/windows/unistd.h b/src/avrdude/windows/unistd.h index b1bc6bf7f..95ba79a34 100644 --- a/src/avrdude/windows/unistd.h +++ b/src/avrdude/windows/unistd.h @@ -45,7 +45,9 @@ extern "C" { #define chdir _chdir #define isatty _isatty #define lseek _lseek +#if _MSC_VER < 1900 #define snprintf _snprintf +#endif #define strncasecmp _strnicmp #define strcasecmp _stricmp #define stat _stat diff --git a/src/libslic3r/Int128.hpp b/src/libslic3r/Int128.hpp index d54b75342..56dc5f461 100644 --- a/src/libslic3r/Int128.hpp +++ b/src/libslic3r/Int128.hpp @@ -53,6 +53,11 @@ #define HAS_INTRINSIC_128_TYPE #endif +#if defined(_MSC_VER) && defined(_WIN64) + #include + #pragma intrinsic(_mul128) +#endif + //------------------------------------------------------------------------------ // Int128 class (enables safe math on signed 64bit integers) // eg Int128 val1((int64_t)9223372036854775807); //ie 2^63 -1 From f7529dbef5cf60ab9f3a7e7e2737f28ad4247a76 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Tue, 29 Jan 2019 15:57:22 +0100 Subject: [PATCH 11/28] Tab: Update print host address and cafile properly, fix #1687 --- src/slic3r/GUI/Field.hpp | 4 +++- src/slic3r/GUI/Tab.cpp | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 3273f84c9..8391a111b 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -115,7 +115,7 @@ public: /// subclasses should overload with a specific version /// Postcondition: Method does not fire the on_change event. virtual void set_value(const boost::any& value, bool change_event) = 0; - + /// Gets a boost::any representing this control. /// subclasses should overload with a specific version virtual boost::any& get_value() = 0; @@ -128,6 +128,8 @@ public: virtual wxString get_tooltip_text(const wxString& default_string); + void field_changed() { on_change_field(); } + // set icon to "UndoToSystemValue" button according to an inheritance of preset // void set_nonsys_btn_icon(const wxBitmap& icon); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 79952f184..c37e04ab9 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1587,11 +1587,11 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [this, parent, optgroup](wxCommandEvent e) { + btn->Bind(wxEVT_BUTTON, [this, parent, optgroup](wxCommandEvent &e) { BonjourDialog dialog(parent); if (dialog.show_and_lookup()) { optgroup->set_value("print_host", std::move(dialog.get_selected()), true); - // FIXME: emit killfocus on the edit widget + optgroup->get_field("print_host")->field_changed(); } }); @@ -1605,7 +1605,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) { + btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { std::unique_ptr host(PrintHost::get_print_host(m_config)); if (! host) { const auto text = wxString::Format("%s", @@ -1646,6 +1646,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) wxFileDialog openFileDialog(this, _(L("Open CA certificate file")), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST); if (openFileDialog.ShowModal() != wxID_CANCEL) { optgroup->set_value("printhost_cafile", std::move(openFileDialog.GetPath()), true); + optgroup->get_field("printhost_cafile")->field_changed(); } }); From 57bd0889c384b4a2420adbfa306de8c8d191b9b4 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 29 Jan 2019 18:07:45 +0100 Subject: [PATCH 12/28] Disabled the experimental pressure equalizer. --- src/libslic3r/CMakeLists.txt | 4 ++-- src/libslic3r/GCode.cpp | 10 ++++++++++ src/libslic3r/GCode.hpp | 7 ++++++- src/libslic3r/Print.cpp | 2 ++ src/libslic3r/PrintConfig.cpp | 5 +++++ src/libslic3r/PrintConfig.hpp | 6 ++++++ src/slic3r/GUI/Preset.cpp | 5 ++++- src/slic3r/GUI/Tab.cpp | 2 ++ 8 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index baf860bd4..270905fce 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -71,8 +71,8 @@ add_library(libslic3r STATIC GCode/CoolingBuffer.hpp GCode/PostProcessor.cpp GCode/PostProcessor.hpp - GCode/PressureEqualizer.cpp - GCode/PressureEqualizer.hpp +# GCode/PressureEqualizer.cpp +# GCode/PressureEqualizer.hpp GCode/PreviewData.cpp GCode/PreviewData.hpp GCode/PrintExtents.cpp diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2a53e0444..66698d4ad 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -662,10 +662,14 @@ void GCode::_do_export(Print &print, FILE *file) m_cooling_buffer = make_unique(*this); if (print.config().spiral_vase.value) m_spiral_vase = make_unique(print.config()); +#ifdef HAS_PRESSURE_EQUALIZER if (print.config().max_volumetric_extrusion_rate_slope_positive.value > 0 || print.config().max_volumetric_extrusion_rate_slope_negative.value > 0) m_pressure_equalizer = make_unique(&print.config()); m_enable_extrusion_role_markers = (bool)m_pressure_equalizer; +#else /* HAS_PRESSURE_EQUALIZER */ + m_enable_extrusion_role_markers = false; +#endif /* HAS_PRESSURE_EQUALIZER */ // Write information on the generator. _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); @@ -918,8 +922,10 @@ void GCode::_do_export(Print &print, FILE *file) this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), © - object.copies().data()); print.throw_if_canceled(); } +#ifdef HAS_PRESSURE_EQUALIZER if (m_pressure_equalizer) _write(file, m_pressure_equalizer->process("", true)); +#endif /* HAS_PRESSURE_EQUALIZER */ ++ finished_objects; // Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed. // Reset it when starting another object from 1st layer. @@ -974,8 +980,10 @@ void GCode::_do_export(Print &print, FILE *file) this->process_layer(file, print, layer.second, layer_tools, size_t(-1)); print.throw_if_canceled(); } +#ifdef HAS_PRESSURE_EQUALIZER if (m_pressure_equalizer) _write(file, m_pressure_equalizer->process("", true)); +#endif /* HAS_PRESSURE_EQUALIZER */ if (m_wipe_tower) // Purge the extruder, pull out the active filament. _write(file, m_wipe_tower->finalize(*this)); @@ -1656,11 +1664,13 @@ void GCode::process_layer( if (m_cooling_buffer) gcode = m_cooling_buffer->process_layer(gcode, layer.id()); +#ifdef HAS_PRESSURE_EQUALIZER // Apply pressure equalization if enabled; // printf("G-code before filter:\n%s\n", gcode.c_str()); if (m_pressure_equalizer) gcode = m_pressure_equalizer->process(gcode.c_str(), false); // printf("G-code after filter:\n%s\n", out.c_str()); +#endif /* HAS_PRESSURE_EQUALIZER */ _write(file, gcode); BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index faa6384cd..21957d32c 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -11,7 +11,6 @@ #include "Print.hpp" #include "PrintConfig.hpp" #include "GCode/CoolingBuffer.hpp" -#include "GCode/PressureEqualizer.hpp" #include "GCode/SpiralVase.hpp" #include "GCode/ToolOrdering.hpp" #include "GCode/WipeTower.hpp" @@ -22,6 +21,10 @@ #include #include +#ifdef HAS_PRESSURE_EQUALIZER +#include "GCode/PressureEqualizer.hpp" +#endif /* HAS_PRESSURE_EQUALIZER */ + namespace Slic3r { // Forward declarations. @@ -306,7 +309,9 @@ protected: std::unique_ptr m_cooling_buffer; std::unique_ptr m_spiral_vase; +#ifdef HAS_PRESSURE_EQUALIZER std::unique_ptr m_pressure_equalizer; +#endif /* HAS_PRESSURE_EQUALIZER */ std::unique_ptr m_wipe_tower; // Heights at which the skirt has already been extruded. diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index ea2d9b03d..3efb18599 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -135,8 +135,10 @@ bool Print::invalidate_state_by_config_options(const std::vectormode = comExpert; def->default_value = new ConfigOptionFloat(0); +#ifdef HAS_PRESSURE_EQUALIZER def = this->add("max_volumetric_extrusion_rate_slope_positive", coFloat); def->label = L("Max volumetric slope positive"); def->tooltip = L("This experimental setting is used to limit the speed of change in extrusion rate. " @@ -1231,6 +1232,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->mode = comExpert; def->default_value = new ConfigOptionFloat(0); +#endif /* HAS_PRESSURE_EQUALIZER */ def = this->add("min_fan_speed", coInts); def->label = L("Min"); @@ -2740,6 +2742,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va "start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start", "seal_position", "vibration_limit", "bed_size", "print_center", "g0", "threads", "pressure_advance", "wipe_tower_per_color_wipe" +#ifndef HAS_PRESSURE_EQUALIZER + , "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative" +#endif /* HAS_PRESSURE_EQUALIZER */ }; if (ignore.find(opt_key) != ignore.end()) { diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 4842156d6..1b218a192 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -20,6 +20,8 @@ #include "libslic3r.h" #include "Config.hpp" +// #define HAS_PRESSURE_EQUALIZER + namespace Slic3r { enum PrinterTechnology @@ -620,8 +622,10 @@ public: ConfigOptionString layer_gcode; ConfigOptionFloat max_print_speed; ConfigOptionFloat max_volumetric_speed; +#ifdef HAS_PRESSURE_EQUALIZER ConfigOptionFloat max_volumetric_extrusion_rate_slope_positive; ConfigOptionFloat max_volumetric_extrusion_rate_slope_negative; +#endif ConfigOptionPercents retract_before_wipe; ConfigOptionFloats retract_length; ConfigOptionFloats retract_length_toolchange; @@ -689,8 +693,10 @@ protected: OPT_PTR(layer_gcode); OPT_PTR(max_print_speed); OPT_PTR(max_volumetric_speed); +#ifdef HAS_PRESSURE_EQUALIZER OPT_PTR(max_volumetric_extrusion_rate_slope_positive); OPT_PTR(max_volumetric_extrusion_rate_slope_negative); +#endif /* HAS_PRESSURE_EQUALIZER */ OPT_PTR(retract_before_wipe); OPT_PTR(retract_length); OPT_PTR(retract_length_toolchange); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index f0473b823..ef1caf035 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -323,7 +323,10 @@ const std::vector& Preset::print_options() "seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "external_fill_pattern", "infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle", "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed", - "max_volumetric_speed", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", + "max_volumetric_speed", +#ifdef HAS_PRESSURE_EQUALIZER + "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", +#endif /* HAS_PRESSURE_EQUALIZER */ "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed", "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed", "bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 79952f184..d8997f954 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1028,8 +1028,10 @@ void TabPrint::build() optgroup = page->new_optgroup(_(L("Autospeed (advanced)"))); optgroup->append_single_option_line("max_print_speed"); optgroup->append_single_option_line("max_volumetric_speed"); +#ifdef HAS_PRESSURE_EQUALIZER optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive"); optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative"); +#endif /* HAS_PRESSURE_EQUALIZER */ page = add_options_page(_(L("Multiple Extruders")), "funnel.png"); optgroup = page->new_optgroup(_(L("Extruders"))); From 49bb90523a9cff9f2688958fdad2e644bb13a811 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 29 Jan 2019 18:28:52 +0100 Subject: [PATCH 13/28] Fix of a G-code comment. Fixes Incorrect filament profile being used during purge - always set to PLA. #1691 --- src/libslic3r/GCode/WipeTowerPrusaMM.cpp | 34 +++++++++++++----------- src/libslic3r/GCode/WipeTowerPrusaMM.hpp | 1 + 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/src/libslic3r/GCode/WipeTowerPrusaMM.cpp index f87969505..031fd9a28 100644 --- a/src/libslic3r/GCode/WipeTowerPrusaMM.cpp +++ b/src/libslic3r/GCode/WipeTowerPrusaMM.cpp @@ -381,22 +381,7 @@ public: Writer& comment_material(WipeTowerPrusaMM::material_type material) { m_gcode += "; material : "; - switch (material) - { - case WipeTowerPrusaMM::PVA: - m_gcode += "#8 (PVA)"; - break; - case WipeTowerPrusaMM::SCAFF: - m_gcode += "#5 (Scaffold)"; - break; - case WipeTowerPrusaMM::FLEX: - m_gcode += "#4 (Flex)"; - break; - default: - m_gcode += "DEFAULT (PLA)"; - break; - } - m_gcode += "\n"; + m_gcode += WipeTowerPrusaMM::to_string(material) + "\n"; return *this; }; @@ -487,6 +472,23 @@ WipeTowerPrusaMM::material_type WipeTowerPrusaMM::parse_material(const char *nam return INVALID; } +std::string WipeTowerPrusaMM::to_string(material_type material) +{ + switch (material) { + case PLA: return "PLA"; + case ABS: return "ABS"; + case PET: return "PET"; + case HIPS: return "HIPS"; + case FLEX: return "FLEX"; + case SCAFF: return "SCAFF"; + case EDGE: return "EDGE"; + case NGEN: return "NGEN"; + case PVA: return "PVA"; + case INVALID: + default: return "INVALID"; + } +} + // Returns gcode to prime the nozzles at the front edge of the print bed. WipeTower::ToolChangeResult WipeTowerPrusaMM::prime( // print_z of the first layer. diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp index 70c9526e6..3f904a483 100644 --- a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp +++ b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp @@ -38,6 +38,7 @@ public: // Parse material name into material_type. static material_type parse_material(const char *name); + static std::string to_string(material_type material); // x -- x coordinates of wipe tower in mm ( left bottom corner ) // y -- y coordinates of wipe tower in mm ( left bottom corner ) From 72e8c7c7562ae4902237b725691ac8880a940d35 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 30 Jan 2019 09:07:29 +0100 Subject: [PATCH 14/28] Updated the github issue template --- .github/ISSUE_TEMPLATE.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 133a8aa84..74dea387a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,5 +1,5 @@ ### Version -_Version of Slic3r used goes here_ +_Version of Slic3r Prusa Edition used goes here_ _Use `About->About Slic3r` for release versions_ @@ -7,6 +7,10 @@ _For -dev versions, use `git describe --tag` or get the hash value for the versi ### Operating system type + version _What OS are you using, and state any version #s_ +_In case of 3D rendering issues, please attach the content of menu Help -> System Info dialog_ + +### 3D printer brand / version + firmware version (if known) +_What 3D printer brand / version are you printing on, is it a stock model or did you modify the printer, what firmware is running on your printer, version of the firmware #s_ ### Behavior * _Describe the problem_ @@ -18,5 +22,5 @@ _What OS are you using, and state any version #s_ _Is this a new feature request?_ -#### STL/Config (.ZIP) where problem occurs -_Upload a zipped copy of an STL and your config (`File -> Export Config`)_ +#### Project File (.3MF) where problem occurs +_Upload a Slic3r PE Project File (.3MF) (`Plater -> Export plate as 3MF` for Slic3r PE 1.41.2 and older, `File -> Save` / `Save Project` for Slic3r PE 1.42.0-alpha and newer)_ From 19c1fc0b3f5e44064d239ed9cf42714e2c35e06e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 30 Jan 2019 10:00:38 +0100 Subject: [PATCH 15/28] Hide slicing results after Delete All command --- src/slic3r/GUI/Plater.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 42e404106..e559be64f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1717,6 +1717,8 @@ void Plater::priv::reset() object_list_changed(); update(); + // The hiding of the slicing results, if shown, is not taken care by the background process, so we do it here + this->sidebar->show_sliced_info_sizer(false); auto& config = wxGetApp().preset_bundle->project_config; config.option("colorprint_heights")->values.clear(); From b6852d8bf227402b36232d03dd519b9455b76845 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 30 Jan 2019 10:05:54 +0100 Subject: [PATCH 16/28] Fixed first binding for "Split to parts" menu item in ObjectList --- src/slic3r/GUI/GUI_ObjectList.cpp | 33 +++++++++++++++++-------------- src/slic3r/GUI/GUI_ObjectList.hpp | 1 + src/slic3r/GUI/MainFrame.cpp | 3 +++ 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 00b074f7d..e9180d39a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -64,12 +64,6 @@ ObjectList::ObjectList(wxWindow* parent) : init_icons(); - // create popup menus for object and part - create_object_popupmenu(&m_menu_object); - create_part_popupmenu(&m_menu_part); - create_sla_object_popupmenu(&m_menu_sla_object); - create_instance_popupmenu(&m_menu_instance); - // describe control behavior Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxEvent& event) { selection_changed(); @@ -141,6 +135,15 @@ void ObjectList::create_objects_ctrl() wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); } +void ObjectList::create_popup_menus() +{ + // create popup menus for object and part + create_object_popupmenu(&m_menu_object); + create_part_popupmenu(&m_menu_part); + create_sla_object_popupmenu(&m_menu_sla_object); + create_instance_popupmenu(&m_menu_instance); +} + void ObjectList::set_tooltip_for_item(const wxPoint& pt) { wxDataViewItem item; @@ -421,9 +424,6 @@ void ObjectList::show_context_menu() if (multiple_selection() && selected_instances_of_same_object()) { wxGetApp().plater()->PopupMenu(&m_menu_instance); - - wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { - evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId()); return; } @@ -442,12 +442,6 @@ void ObjectList::show_context_menu() append_menu_item_settings(menu); wxGetApp().plater()->PopupMenu(menu); - - wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { - evt.Enable(is_splittable()); }, m_menu_item_split->GetId()); - - wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { - evt.Enable(is_splittable()); }, m_menu_item_split_part->GetId()); } } @@ -973,6 +967,9 @@ void ObjectList::create_object_popupmenu(wxMenu *menu) // rest of a object_menu will be added later in: // - append_menu_items_add_volume() -> for "Add (volumes)" // - append_menu_item_settings() -> for "Add (settings)" + + wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { + evt.Enable(is_splittable()); }, m_menu_item_split->GetId()); } void ObjectList::create_sla_object_popupmenu(wxMenu *menu) @@ -991,11 +988,17 @@ void ObjectList::create_part_popupmenu(wxMenu *menu) // rest of a object_sla_menu will be added later in: // - append_menu_item_settings() -> for "Add (settings)" + + wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { + evt.Enable(is_splittable()); }, m_menu_item_split_part->GetId()); } void ObjectList::create_instance_popupmenu(wxMenu*menu) { m_menu_item_split_instances = append_menu_item_instance_to_object(menu); + + wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { + evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId()); } wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 93a3ba60f..741fa3741 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -153,6 +153,7 @@ public: void create_objects_ctrl(); + void create_popup_menus(); wxDataViewColumn* create_objects_list_extruder_column(int extruders_count); void update_objects_list_extruder_column(int extruders_count); // show/hide "Extruder" column for Objects List diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 51f1c5f19..947dd59bd 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -22,6 +22,7 @@ #include "AppConfig.hpp" #include "PrintHostDialogs.hpp" #include "wxExtensions.hpp" +#include "GUI_ObjectList.hpp" #include "I18N.hpp" #include @@ -132,6 +133,8 @@ void MainFrame::init_tabpanel() wxGetApp().plater_ = m_plater; m_tabpanel->AddPage(m_plater, _(L("Plater"))); + wxGetApp().obj_list()->create_popup_menus(); + // The following event is emited by Tab implementation on config value change. Bind(EVT_TAB_VALUE_CHANGED, &MainFrame::on_value_changed, this); From 411c02fef3efe1329baf1192e2d8645064d93780 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 30 Jan 2019 11:35:37 +0100 Subject: [PATCH 17/28] Implemented object/part renaming under OSX, using popup_menu --- src/slic3r/GUI/GUI_ObjectList.cpp | 58 ++++++++++++++++++++++++++++++- src/slic3r/GUI/GUI_ObjectList.hpp | 4 ++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index e9180d39a..cb031a8d0 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -313,7 +313,7 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item) wxGetApp().plater()->update(); } -void ObjectList::update_name_in_model(const wxDataViewItem& item) +void ObjectList::update_name_in_model(const wxDataViewItem& item) const { const int obj_idx = m_objects_model->GetObjectIdByItem(item); if (obj_idx < 0) return; @@ -958,8 +958,18 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu) [this](wxCommandEvent&) { split_instances(); }, "", menu); } +wxMenuItem* ObjectList::append_menu_item_rename(wxMenu* menu) +{ + return append_menu_item(menu, wxID_ANY, _(L("Rename")), "", + [this](wxCommandEvent&) { rename_item(); }, "", menu); +} + void ObjectList::create_object_popupmenu(wxMenu *menu) { +#ifdef __WXOSX__ + append_menu_item_rename(menu); +#endif // __WXOSX__ + // Split object to parts m_menu_item_split = append_menu_item_split(menu); menu->AppendSeparator(); @@ -980,6 +990,10 @@ void ObjectList::create_sla_object_popupmenu(wxMenu *menu) void ObjectList::create_part_popupmenu(wxMenu *menu) { +#ifdef __WXOSX__ + append_menu_item_rename(menu); +#endif // __WXOSX__ + m_menu_item_split_part = append_menu_item_split(menu); // Append change part type @@ -2055,6 +2069,48 @@ void ObjectList::split_instances() instances_to_separated_object(obj_idx, inst_idxs); } +void ObjectList::rename_item() +{ + const wxDataViewItem item = GetSelection(); + if (!item || !(m_objects_model->GetItemType(item) & (itVolume | itObject))) + return ; + + const wxString new_name = wxGetTextFromUser(_(L("Enter new name"))+":", _(L("Renaming")), + m_objects_model->GetName(item), this); + + bool is_unusable_symbol = false; + std::string chosen_name = Slic3r::normalize_utf8_nfc(new_name.ToUTF8()); + const char* unusable_symbols = "<>:/\\|?*\""; + for (size_t i = 0; i < std::strlen(unusable_symbols); i++) { + if (chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) { + is_unusable_symbol = true; + } + } + + if (is_unusable_symbol) { + show_error(this, _(L("The supplied name is not valid;")) + "\n" + + _(L("the following characters are not allowed:")) + " <>:/\\|?*\""); + return; + } + + // The icon can't be edited so get its old value and reuse it. + wxVariant valueOld; + m_objects_model->GetValue(valueOld, item, 0); + + PrusaDataViewBitmapText bmpText; + bmpText << valueOld; + + // But replace the text with the value entered by user. + bmpText.SetText(new_name); + + wxVariant value; + value << bmpText; + m_objects_model->SetValue(value, item, 0); + m_objects_model->ItemChanged(item); + + update_name_in_model(item); +} + void ObjectList::ItemValueChanged(wxDataViewEvent &event) { if (event.GetColumn() == 0) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 741fa3741..86e2167dd 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -161,7 +161,7 @@ public: // update extruder in current config void update_extruder_in_config(const wxDataViewItem& item); // update changed name in the object model - void update_name_in_model(const wxDataViewItem& item); + void update_name_in_model(const wxDataViewItem& item) const; void update_extruder_values_for_items(const int max_extruder); void init_icons(); @@ -182,6 +182,7 @@ public: wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu); wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu); + wxMenuItem* append_menu_item_rename(wxMenu* menu); void create_object_popupmenu(wxMenu *menu); void create_sla_object_popupmenu(wxMenu*menu); void create_part_popupmenu(wxMenu*menu); @@ -263,6 +264,7 @@ public: void instances_to_separated_object(const int obj_idx, const std::set& inst_idx); void split_instances(); + void rename_item(); private: void OnChar(wxKeyEvent& event); From 460cf820afe95951eea41ab6a0ae1a58e64c5937 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 30 Jan 2019 12:10:26 +0100 Subject: [PATCH 18/28] Some optimizations of the color print preview. --- src/libslic3r/GCode/PreviewData.cpp | 11 ++++------- src/slic3r/GUI/GLCanvas3D.cpp | 22 +++------------------- src/slic3r/GUI/GUI_Preview.cpp | 14 ++++++++------ 3 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index cd6be3db1..8eba6801e 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -479,16 +479,13 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: } case Extrusion::ColorPrint: { - const size_t color_cnt = tool_colors.size()/4; + const int color_cnt = (int)tool_colors.size()/4; - const auto color_print_cnt = cp_values.size(); - for (size_t i = color_print_cnt; i >= 0 ; --i) + const auto color_print_cnt = (int)cp_values.size(); + for (int i = color_print_cnt; i >= 0 ; --i) { - size_t val = i; - while (val >= color_cnt) - val -= color_cnt; GCodePreviewData::Color color; - ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + val * 4), 4 * sizeof(float)); + ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (i % color_cnt) * 4), 4 * sizeof(float)); if (color_print_cnt == 0) { items.emplace_back(Slic3r::I18N::translate(L("Default print color")), color); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 52030df48..65e8cd3fb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7288,31 +7288,15 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; } int volume_idx(int extruder, int feature) const { - return this->color_by_tool() ? std::min(this->number_tools() - 1, std::max(extruder - 1, 0)) : feature; + return this->color_by_color_print() ? 0 : this->color_by_tool() ? std::min(this->number_tools() - 1, std::max(extruder - 1, 0)) : feature; } // For coloring by a color_print(M600), return a parsed color. bool color_by_color_print() const { return color_print_values!=nullptr; } const float* color_print_by_layer_idx(const size_t layer_idx) const { - double z = layers[layer_idx]->print_z; - size_t layer = 0; - const size_t clr_change_cnt = color_print_values->size(); - for (size_t i = 0; i < clr_change_cnt; i++) - { - if (z < (*color_print_values)[i]-EPSILON) { - layer = i; - break; - } - if (layer == 0 && i == clr_change_cnt - 1) - layer = clr_change_cnt; - } - - const size_t clr_cnt = number_tools(); - while (layer >= clr_cnt) - layer -= clr_cnt; - - return color_tool(layer); + auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z - EPSILON); + return color_tool((it - color_print_values->begin()) % number_tools()); } } ctxt; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index eb35aa61e..c2a769586 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -737,9 +737,12 @@ void Preview::load_print_as_fff() if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) { colors = GCodePreviewData::ColorPrintColors(); - - const auto& config = wxGetApp().preset_bundle->full_config(); - color_print_values = config.option("colorprint_heights")->values; + if (! gcode_preview_data_valid) { + //FIXME accessing full_config() is pretty expensive. + // Only initialize color_print_values for the initial preview, not for the full preview where the color_print_values is extracted from the G-code. + const auto& config = wxGetApp().preset_bundle->full_config(); + color_print_values = config.option("colorprint_heights")->values; + } } else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) { @@ -758,10 +761,9 @@ void Preview::load_print_as_fff() color = "#FFFFFF"; } - colors.push_back(color); + colors.emplace_back(color); } - if (!color_print_values.empty()) - color_print_values.clear(); + color_print_values.clear(); } if (IsShown()) From 7957675a97cade5b2bcf99cda03c5c5e542f74b8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 30 Jan 2019 13:26:02 +0100 Subject: [PATCH 19/28] Fix to my last commit --- src/slic3r/GUI/GUI_ObjectList.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index cb031a8d0..a38248d3a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -984,6 +984,9 @@ void ObjectList::create_object_popupmenu(wxMenu *menu) void ObjectList::create_sla_object_popupmenu(wxMenu *menu) { +#ifdef __WXOSX__ + append_menu_item_rename(menu); +#endif // __WXOSX__ // rest of a object_sla_menu will be added later in: // - append_menu_item_settings() -> for "Add (settings)" } @@ -2078,6 +2081,9 @@ void ObjectList::rename_item() const wxString new_name = wxGetTextFromUser(_(L("Enter new name"))+":", _(L("Renaming")), m_objects_model->GetName(item), this); + if (new_name.IsEmpty()) + return; + bool is_unusable_symbol = false; std::string chosen_name = Slic3r::normalize_utf8_nfc(new_name.ToUTF8()); const char* unusable_symbols = "<>:/\\|?*\""; From 5a28693ff42589084c467f4991882fac6504204c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 30 Jan 2019 14:45:18 +0100 Subject: [PATCH 20/28] Updated draw_colored_band() according to the new colors. + some code refactoring --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++-- src/slic3r/GUI/GUI_ObjectList.cpp | 14 ++++---------- src/slic3r/GUI/GUI_ObjectList.hpp | 3 --- src/slic3r/GUI/GUI_Preview.cpp | 2 +- src/slic3r/GUI/wxExtensions.cpp | 14 +++++++------- 5 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 65e8cd3fb..982ac4a26 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3753,7 +3753,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePrevie { if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) { - const auto& config = wxGetApp().preset_bundle->full_config(); + auto& config = wxGetApp().preset_bundle->project_config; const std::vector& color_print_values = config.option("colorprint_heights")->values; const int values_cnt = color_print_values.size(); if (values_cnt > 0) { @@ -7295,7 +7295,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c bool color_by_color_print() const { return color_print_values!=nullptr; } const float* color_print_by_layer_idx(const size_t layer_idx) const { - auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z - EPSILON); + auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON); return color_tool((it - color_print_values->begin()) % number_tools()); } } ctxt; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a38248d3a..c2f9a4a5c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -100,8 +100,6 @@ ObjectList::ObjectList(wxWindow* parent) : ObjectList::~ObjectList() { - if (m_default_config) - delete m_default_config; } void ObjectList::create_objects_ctrl() @@ -749,10 +747,8 @@ void ObjectList::get_settings_choice(const wxString& category_name) const ConfigOption* option = from_config.option(opt_key); if (!option) { // if current option doesn't exist in prints.get_edited_preset(), - // get it from m_default_config - if (m_default_config) delete m_default_config; - m_default_config = DynamicPrintConfig::new_from_defaults_keys(get_options(false)); - option = m_default_config->option(opt_key); + // get it from default config values + option = DynamicPrintConfig::new_from_defaults_keys({ opt_key })->option(opt_key); } m_config->set_key_value(opt_key, option->clone()); } @@ -776,10 +772,8 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name) const ConfigOption* option = from_config.option(opt_key); if (!option) { // if current option doesn't exist in prints.get_edited_preset(), - // get it from m_default_config - if (m_default_config) delete m_default_config; - m_default_config = DynamicPrintConfig::new_from_defaults_keys(get_options(false)); - option = m_default_config->option(opt_key); + // get it from default config values + option = DynamicPrintConfig::new_from_defaults_keys({ opt_key })->option(opt_key); } m_config->set_key_value(opt_key, option->clone()); } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 86e2167dd..66e142394 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -97,9 +97,6 @@ class ObjectList : public wxDataViewCtrl } m_dragged_data; wxBoxSizer *m_sizer {nullptr}; - - DynamicPrintConfig *m_default_config {nullptr}; - wxWindow *m_parent {nullptr}; wxBitmap m_bmp_modifiermesh; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index c2a769586..b594d0fef 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -740,7 +740,7 @@ void Preview::load_print_as_fff() if (! gcode_preview_data_valid) { //FIXME accessing full_config() is pretty expensive. // Only initialize color_print_values for the initial preview, not for the full preview where the color_print_values is extracted from the G-code. - const auto& config = wxGetApp().preset_bundle->full_config(); + const auto& config = wxGetApp().preset_bundle->project_config; color_print_values = config.option("colorprint_heights")->values; } } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 238a36c74..d24db63ea 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1668,7 +1668,7 @@ void PrusaDoubleSlider::render() // draw colored band on the background of a scroll line // and only in a case of no-empty m_values -// draw_colored_band(dc); + draw_colored_band(dc); // draw line draw_scroll_line(dc, lower_pos, higher_pos); @@ -1867,8 +1867,10 @@ void PrusaDoubleSlider::draw_colored_band(wxDC& dc) return; } - const std::vector& clr_bytes = Slic3r::GCodePreviewData::Range::Default_Colors[0].as_bytes(); - wxColour clr = wxColour(clr_bytes[0], clr_bytes[1], clr_bytes[2], clr_bytes[3]); + const std::vector& colors = Slic3r::GCodePreviewData::ColorPrintColors(); + const size_t colors_cnt = colors.size(); + + wxColour clr(colors[0]); dc.SetPen(clr); dc.SetBrush(clr); dc.DrawRectangle(main_band); @@ -1876,15 +1878,13 @@ void PrusaDoubleSlider::draw_colored_band(wxDC& dc) int i = 1; for (auto tick : m_ticks) { - if (i == Slic3r::GCodePreviewData::Range::Colors_Count) + if (i == colors_cnt) i = 0; const wxCoord pos = get_position_from_value(tick); is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) : main_band.SetBottom(pos-1); - const std::vector& clr_b = Slic3r::GCodePreviewData::Range::Default_Colors[i].as_bytes(); - - clr = wxColour(clr_b[0], clr_b[1], clr_b[2], clr_b[3]); + clr = wxColour(colors[i]); dc.SetPen(clr); dc.SetBrush(clr); dc.DrawRectangle(main_band); From eec289961ac81c0d631be132360acd681f01f379 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 30 Jan 2019 15:27:11 +0100 Subject: [PATCH 21/28] Removed Microsoft specific _DEBUG flag from the Unix systems. Made condional compilation of assert code based on #ifndef NDEBUG instead of #ifdef _DEBUG to compile on Unix systems. --- CMakeLists.txt | 3 +-- src/slic3r/GUI/GLCanvas3D.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e42e24e9..90ebd1e5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,9 +86,8 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) if(NOT WIN32) - # Add DEBUG flags for the debug builds in a way the Visual Studio adds these flags. + # Add DEBUG flags to debug builds. add_compile_options("$<$:-DDEBUG>") - add_compile_options("$<$:-D_DEBUG>") endif() # To be able to link libslic3r with the Perl XS module. diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 982ac4a26..de3c2e6aa 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1793,12 +1793,12 @@ static double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to)); Vec3d axis = angle_axis.axis(); double angle = angle_axis.angle(); -#ifdef _DEBUG +#ifndef NDEBUG if (std::abs(angle) > 1e-8) { assert(std::abs(axis.x()) < 1e-8); assert(std::abs(axis.y()) < 1e-8); } -#endif /* _DEBUG */ +#endif /* NDEBUG */ return (axis.z() < 0) ? -angle : angle; } @@ -2786,7 +2786,7 @@ void GLCanvas3D::Selection::_render_sidebar_size_hint(Axis axis, double length) { } -#ifdef _DEBUG +#ifndef NDEBUG static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) { Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to)); @@ -2820,7 +2820,7 @@ static void verify_instances_rotation_synchronized(const Model &model, const GLV } } } -#endif /* _DEBUG */ +#endif /* NDEBUG */ void GLCanvas3D::Selection::_synchronize_unselected_instances(SyncRotationType sync_rotation_type) { @@ -2880,9 +2880,9 @@ void GLCanvas3D::Selection::_synchronize_unselected_instances(SyncRotationType s } } -#ifdef _DEBUG +#ifndef NDEBUG verify_instances_rotation_synchronized(*m_model, *m_volumes); -#endif /* _DEBUG */ +#endif /* NDEBUG */ } void GLCanvas3D::Selection::_synchronize_unselected_volumes() @@ -4681,10 +4681,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re } if (printer_technology == ptSLA) { const SLAPrint *sla_print = this->sla_print(); - #ifdef _DEBUG + #ifndef NDEBUG // Verify that the SLAPrint object is synchronized with m_model. check_model_ids_equal(*m_model, sla_print->model()); - #endif /* _DEBUG */ + #endif /* NDEBUG */ sla_support_state.reserve(sla_print->objects().size()); for (const SLAPrintObject *print_object : sla_print->objects()) { SLASupportState state; From a5ec9511805cc55334e7440ac27f528646472452 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 30 Jan 2019 16:27:07 +0100 Subject: [PATCH 22/28] Added menu item for the "Fix through the Netfabb" --- src/slic3r/GUI/GUI_ObjectList.cpp | 35 +++++++++++++++++++++++++++++-- src/slic3r/GUI/GUI_ObjectList.hpp | 5 +++-- src/slic3r/GUI/Plater.cpp | 8 ++++--- src/slic3r/GUI/Plater.hpp | 2 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index c2f9a4a5c..57c01a447 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -952,10 +952,20 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu) [this](wxCommandEvent&) { split_instances(); }, "", menu); } -wxMenuItem* ObjectList::append_menu_item_rename(wxMenu* menu) +void ObjectList::append_menu_item_rename(wxMenu* menu) { - return append_menu_item(menu, wxID_ANY, _(L("Rename")), "", + append_menu_item(menu, wxID_ANY, _(L("Rename")), "", [this](wxCommandEvent&) { rename_item(); }, "", menu); + menu->AppendSeparator(); +} + +void ObjectList::append_menu_item_fix_through_netfabb(wxMenu* menu) +{ + if (!is_windows10()) + return; + append_menu_item(menu, wxID_ANY, _(L("Fix through the Netfabb")), "", + [this](wxCommandEvent&) { fix_through_netfabb(); }, "", menu); + menu->AppendSeparator(); } void ObjectList::create_object_popupmenu(wxMenu *menu) @@ -964,6 +974,8 @@ void ObjectList::create_object_popupmenu(wxMenu *menu) append_menu_item_rename(menu); #endif // __WXOSX__ + append_menu_item_fix_through_netfabb(menu); + // Split object to parts m_menu_item_split = append_menu_item_split(menu); menu->AppendSeparator(); @@ -981,6 +993,8 @@ void ObjectList::create_sla_object_popupmenu(wxMenu *menu) #ifdef __WXOSX__ append_menu_item_rename(menu); #endif // __WXOSX__ + + append_menu_item_fix_through_netfabb(menu); // rest of a object_sla_menu will be added later in: // - append_menu_item_settings() -> for "Add (settings)" } @@ -991,6 +1005,8 @@ void ObjectList::create_part_popupmenu(wxMenu *menu) append_menu_item_rename(menu); #endif // __WXOSX__ + append_menu_item_fix_through_netfabb(menu); + m_menu_item_split_part = append_menu_item_split(menu); // Append change part type @@ -2111,6 +2127,21 @@ void ObjectList::rename_item() update_name_in_model(item); } +void ObjectList::fix_through_netfabb() const +{ + const wxDataViewItem item = GetSelection(); + if (!item) + return; + + ItemType type = m_objects_model->GetItemType(item); + + if (type & itObject) + wxGetApp().plater()->fix_through_netfabb(m_objects_model->GetIdByItem(item)); + else if (type & itVolume) + wxGetApp().plater()->fix_through_netfabb(m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)), + m_objects_model->GetVolumeIdByItem(item)); +} + void ObjectList::ItemValueChanged(wxDataViewEvent &event) { if (event.GetColumn() == 0) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 66e142394..e572bec82 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -179,7 +179,8 @@ public: wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu); wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu); - wxMenuItem* append_menu_item_rename(wxMenu* menu); + void append_menu_item_rename(wxMenu* menu); + void append_menu_item_fix_through_netfabb(wxMenu* menu); void create_object_popupmenu(wxMenu *menu); void create_sla_object_popupmenu(wxMenu*menu); void create_part_popupmenu(wxMenu*menu); @@ -262,7 +263,7 @@ public: void instances_to_separated_object(const int obj_idx, const std::set& inst_idx); void split_instances(); void rename_item(); - + void fix_through_netfabb() const; private: void OnChar(wxKeyEvent& event); void OnContextMenu(wxDataViewEvent &event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e559be64f..4902cf1c9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1031,7 +1031,7 @@ struct Plater::priv void update_restart_background_process(bool force_scene_update, bool force_preview_update); void export_gcode(fs::path output_path, PrintHostJob upload_job); void reload_from_disk(); - void fix_through_netfabb(const int obj_idx); + void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); void set_current_panel(wxPanel* panel); @@ -2106,7 +2106,7 @@ void Plater::priv::reload_from_disk() remove(obj_orig_idx); } -void Plater::priv::fix_through_netfabb(const int obj_idx) +void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { if (obj_idx < 0) return; @@ -2440,6 +2440,8 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ } menu->AppendSeparator(); + sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu); + wxMenu* mirror_menu = new wxMenu(); if (mirror_menu == nullptr) return false; @@ -3150,7 +3152,7 @@ void Plater::changed_object(int obj_idx) this->p->schedule_background_process(); } -void Plater::fix_through_netfabb(const int obj_idx) { p->fix_through_netfabb(obj_idx); } +void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); } void Plater::update_object_menu() { p->update_object_menu(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 7b19d6f31..09b7348d5 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -147,7 +147,7 @@ public: void export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path()); void reslice(); void changed_object(int obj_idx); - void fix_through_netfabb(const int obj_idx); + void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); void send_gcode(); void on_extruders_change(int extruders_count); From ed9a924880a0eb12a5d0e6e29108d211da953a66 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 30 Jan 2019 19:02:30 +0100 Subject: [PATCH 23/28] Added missing GL context "Set Current" calls before loading data into vertex buffers. Changed behavior of Canvas3D::on_render() to postpone rendering to idle, as on OSX the paint events happen directly from control updates, if the control update triggers Canvas3D window rescaling. With this change, rendering only happens from idle handler consistently. --- src/slic3r/GUI/GLCanvas3D.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index de3c2e6aa..299341cd8 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4627,6 +4627,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr)) return; + _set_current(); + struct ModelVolumeState { ModelVolumeState(const GLVolume *volume) : model_volume(nullptr), geometry_id(volume->geometry_id), volume_idx(-1) {} @@ -4933,6 +4935,8 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const const Print *print = this->fff_print(); if ((m_canvas != nullptr) && (print != nullptr)) { + _set_current(); + std::vector tool_colors = _parse_colors(str_tool_colors); if (m_volumes.empty()) @@ -4970,6 +4974,7 @@ void GLCanvas3D::load_sla_preview() const SLAPrint* print = this->sla_print(); if ((m_canvas != nullptr) && (print != nullptr)) { + _set_current(); _load_shells_sla(); } } @@ -4980,6 +4985,8 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c if (print == nullptr) return; + _set_current(); + _load_print_toolpaths(); _load_wipe_tower_toolpaths(str_tool_colors); for (const PrintObject* object : print->objects()) @@ -5650,7 +5657,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) void GLCanvas3D::on_paint(wxPaintEvent& evt) { - render(); + m_dirty = true; } void GLCanvas3D::on_key_down(wxKeyEvent& evt) From 991632add5344f4275609963564ef5bb73335887 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 30 Jan 2019 19:48:26 +0100 Subject: [PATCH 24/28] GLCanvas3d::on_render(): if not intialized yet, Call render directly, so it gets initialized immediately, not from On Idle handler. --- src/slic3r/GUI/GLCanvas3D.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 299341cd8..e2cee2ce9 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5657,7 +5657,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) void GLCanvas3D::on_paint(wxPaintEvent& evt) { - m_dirty = true; + if (m_initialized) + m_dirty = true; + else + // Call render directly, so it gets initialized immediately, not from On Idle handler. + this->render(); } void GLCanvas3D::on_key_down(wxKeyEvent& evt) From 4b1cc282c87c83a9ca573629a6d167ce78a17b90 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Jan 2019 08:47:23 +0100 Subject: [PATCH 25/28] replace #ifdef _DEBUG with #ifndef NDEBUG --- src/libslic3r/Model.cpp | 4 ++-- src/libslic3r/Model.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 86bd0d03b..feba1eb01 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1686,7 +1686,7 @@ bool model_volume_list_changed(const ModelObject &model_object_old, const ModelO return false; } -#ifdef _DEBUG +#ifndef NDEBUG // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique. void check_model_ids_validity(const Model &model) { @@ -1732,6 +1732,6 @@ void check_model_ids_equal(const Model &model1, const Model &model2) } } } -#endif /* _DEBUG */ +#endif /* NDEBUG */ } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 0ae238510..ba109246a 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -629,11 +629,11 @@ extern bool model_object_list_extended(const Model &model_old, const Model &mode // than the old ModelObject. extern bool model_volume_list_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, const ModelVolume::Type type); -#ifdef _DEBUG +#ifndef NDEBUG // Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique. void check_model_ids_validity(const Model &model); void check_model_ids_equal(const Model &model1, const Model &model2); -#endif /* _DEBUG */ +#endif /* NDEBUG */ } From 73280d48ed13604eca2de28e6037ca9193cd4cd7 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 31 Jan 2019 09:08:40 +0100 Subject: [PATCH 26/28] Fixed name of the exported project file to respect the object name. --- src/libslic3r/Model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 86bd0d03b..fd814976a 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -552,7 +552,7 @@ std::string Model::propose_export_file_name() const for (const ModelObject *model_object : this->objects) for (ModelInstance *model_instance : model_object->instances) if (model_instance->is_printable()) - return model_object->input_file; + return model_object->name.empty() ? model_object->input_file : model_object->name; return std::string(); } From 0a72a4e7ad7d6384be3ef8ca49edef9b483eee8d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Jan 2019 09:15:43 +0100 Subject: [PATCH 27/28] GLCanvas3D -> added call _set_current() to method accessing GPU memory --- src/slic3r/GUI/GLCanvas3D.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e2cee2ce9..0a6dd52c0 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4173,6 +4173,8 @@ unsigned int GLCanvas3D::get_volumes_count() const void GLCanvas3D::reset_volumes() { + _set_current(); + if (!m_volumes.empty()) { m_selection.clear(); @@ -5712,6 +5714,7 @@ Point GLCanvas3D::get_local_mouse_position() const void GLCanvas3D::reset_legend_texture() { + _set_current(); m_legend_texture.reset(); } @@ -8334,6 +8337,8 @@ void GLCanvas3D::_update_toolpath_volumes_outside_state() void GLCanvas3D::_show_warning_texture_if_needed() { + _set_current(); + if (_is_any_volume_outside()) { enable_warning_texture(true); From f1470966a53eb893c82b5e0d6f8abe62eac12a35 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 31 Jan 2019 09:37:27 +0100 Subject: [PATCH 28/28] glsafe macro to test for the glGetError in debug mode --- src/slic3r/GUI/3DScene.cpp | 297 ++++++++++++++++++++----------------- src/slic3r/GUI/3DScene.hpp | 13 ++ 2 files changed, 172 insertions(+), 138 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index d10d9e0eb..fd1645c9e 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -35,6 +35,27 @@ #include "GUI.hpp" +#ifdef HAS_GLSAFE +void glAssertRecentCallImpl() +{ + GLenum err = glGetError(); + if (err == GL_NO_ERROR) + return; + const char *sErr = 0; + switch (err) { + case GL_INVALID_ENUM: sErr = "Invalid Enum"; break; + case GL_INVALID_VALUE: sErr = "Invalid Value"; break; + case GL_INVALID_OPERATION: sErr = "Invalid Operation"; break; + case GL_STACK_OVERFLOW: sErr = "Stack Overflow"; break; + case GL_STACK_UNDERFLOW: sErr = "Stack Underflow"; break; + case GL_OUT_OF_MEMORY: sErr = "Out Of Memory"; break; + default: sErr = "Unknown"; break; + } + BOOST_LOG_TRIVIAL(error) << "OpenGL error " << (int)err << ": " << sErr; + assert(false); +} +#endif + namespace Slic3r { void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh) @@ -81,25 +102,25 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs) if (use_VBOs) { if (! empty()) { - glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id); - glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id); - glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glsafe(glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0)); this->vertices_and_normals_interleaved.clear(); } if (! this->triangle_indices.empty()) { - glGenBuffers(1, &this->triangle_indices_VBO_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW); + glsafe(glGenBuffers(1, &this->triangle_indices_VBO_id)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW)); this->triangle_indices.clear(); } if (! this->quad_indices.empty()) { - glGenBuffers(1, &this->quad_indices_VBO_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW); + glsafe(glGenBuffers(1, &this->quad_indices_VBO_id)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW)); this->quad_indices.clear(); } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } this->shrink_to_fit(); } @@ -107,15 +128,15 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs) void GLIndexedVertexArray::release_geometry() { if (this->vertices_and_normals_interleaved_VBO_id) { - glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id); + glsafe(glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); this->vertices_and_normals_interleaved_VBO_id = 0; } if (this->triangle_indices_VBO_id) { - glDeleteBuffers(1, &this->triangle_indices_VBO_id); + glsafe(glDeleteBuffers(1, &this->triangle_indices_VBO_id)); this->triangle_indices_VBO_id = 0; } if (this->quad_indices_VBO_id) { - glDeleteBuffers(1, &this->quad_indices_VBO_id); + glsafe(glDeleteBuffers(1, &this->quad_indices_VBO_id)); this->quad_indices_VBO_id = 0; } this->clear(); @@ -125,42 +146,42 @@ void GLIndexedVertexArray::release_geometry() void GLIndexedVertexArray::render() const { if (this->vertices_and_normals_interleaved_VBO_id) { - glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id); - glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))); - glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); } else { - glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3); - glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()); + glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3)); + glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data())); } - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); + glsafe(glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(glEnableClientState(GL_NORMAL_ARRAY)); if (this->indexed()) { if (this->vertices_and_normals_interleaved_VBO_id) { // Render using the Vertex Buffer Objects. if (this->triangle_indices_size > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id); - glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr)); } if (this->quad_indices_size > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id); - glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr)); } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { // Render in an immediate mode. if (! this->triangle_indices.empty()) - glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data()); + glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data())); if (! this->quad_indices.empty()) - glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data()); + glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data())); } } else - glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6)); + glsafe(glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6))); if (this->vertices_and_normals_interleaved_VBO_id) - glBindBuffer(GL_ARRAY_BUFFER, 0); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(glDisableClientState(GL_NORMAL_ARRAY)); } void GLIndexedVertexArray::render( @@ -173,35 +194,35 @@ void GLIndexedVertexArray::render( if (this->vertices_and_normals_interleaved_VBO_id) { // Render using the Vertex Buffer Objects. - glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id); - glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))); - glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); + glsafe(glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(glEnableClientState(GL_NORMAL_ARRAY)); if (this->triangle_indices_size > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id); - glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4))); } if (this->quad_indices_size > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id); - glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4))); } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { // Render in an immediate mode. - glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3); - glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); + glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3)); + glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data())); + glsafe(glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(glEnableClientState(GL_NORMAL_ARRAY)); if (! this->triangle_indices.empty()) - glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first)); + glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first))); if (! this->quad_indices.empty()) - glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first)); + glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first))); } - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + glsafe(glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(glDisableClientState(GL_NORMAL_ARRAY)); } const float GLVolume::SELECTED_COLOR[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; @@ -375,15 +396,15 @@ void GLVolume::render() const if (!is_active) return; - ::glCullFace(GL_BACK); - ::glPushMatrix(); + glsafe(::glCullFace(GL_BACK)); + glsafe(::glPushMatrix()); - ::glMultMatrixd(world_matrix().data()); + glsafe(::glMultMatrixd(world_matrix().data())); if (this->indexed_vertex_array.indexed()) this->indexed_vertex_array.render(this->tverts_range, this->qverts_range); else this->indexed_vertex_array.render(); - ::glPopMatrix(); + glsafe(::glPopMatrix()); } void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) const @@ -398,63 +419,63 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first)); if (n_triangles + n_quads == 0) { - ::glDisableClientState(GL_VERTEX_ARRAY); - ::glDisableClientState(GL_NORMAL_ARRAY); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); if (color_id >= 0) { float color[4]; ::memcpy((void*)color, (const void*)render_color, 4 * sizeof(float)); - ::glUniform4fv(color_id, 1, (const GLfloat*)color); + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color)); } else - ::glColor4fv(render_color); + glsafe(::glColor4fv(render_color)); if (detection_id != -1) - ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0); + glsafe(::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0)); if (worldmatrix_id != -1) - ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data()); + glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data())); render(); - ::glEnableClientState(GL_VERTEX_ARRAY); - ::glEnableClientState(GL_NORMAL_ARRAY); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); return; } if (color_id >= 0) - ::glUniform4fv(color_id, 1, (const GLfloat*)render_color); + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)render_color)); else - ::glColor4fv(render_color); + glsafe(::glColor4fv(render_color)); if (detection_id != -1) - ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0); + glsafe(::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0)); if (worldmatrix_id != -1) - ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data()); + glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().data())); - ::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id); - ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))); - ::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); - ::glPushMatrix(); + glsafe(::glPushMatrix()); - ::glMultMatrixd(world_matrix().data()); + glsafe(::glMultMatrixd(world_matrix().data())); if (n_triangles > 0) { - ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.triangle_indices_VBO_id); - ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.triangle_indices_VBO_id)); + glsafe(::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4))); } if (n_quads > 0) { - ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.quad_indices_VBO_id); - ::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.quad_indices_VBO_id)); + glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4))); } - ::glPopMatrix(); + glsafe(::glPopMatrix()); } void GLVolume::render_legacy() const @@ -467,33 +488,33 @@ void GLVolume::render_legacy() const GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first)); if (n_triangles + n_quads == 0) { - ::glDisableClientState(GL_VERTEX_ARRAY); - ::glDisableClientState(GL_NORMAL_ARRAY); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - ::glColor4fv(render_color); + glsafe(::glColor4fv(render_color)); render(); - ::glEnableClientState(GL_VERTEX_ARRAY); - ::glEnableClientState(GL_NORMAL_ARRAY); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); return; } - ::glColor4fv(render_color); - ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data() + 3); - ::glNormalPointer(GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data()); + glsafe(::glColor4fv(render_color)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data() + 3)); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data())); - ::glPushMatrix(); + glsafe(::glPushMatrix()); - ::glMultMatrixd(world_matrix().data()); + glsafe(::glMultMatrixd(world_matrix().data())); if (n_triangles > 0) - ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first); + glsafe(::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first)); if (n_quads > 0) - ::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first); + glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first)); - ::glPopMatrix(); + glsafe(::glPopMatrix()); } std::vector GLVolumeCollection::load_object( @@ -705,7 +726,7 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum if ((type == GLVolumeCollection::Transparent) && (list.size() > 1)) { Transform3d modelview_matrix; - ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()); + glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data())); for (GLVolumeWithZ& volume : list) { @@ -722,18 +743,18 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, std::function filter_func) const { - ::glEnable(GL_BLEND); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - ::glCullFace(GL_BACK); + glsafe(::glCullFace(GL_BACK)); if (disable_cullface) - ::glDisable(GL_CULL_FACE); + glsafe(::glDisable(GL_CULL_FACE)); - ::glEnableClientState(GL_VERTEX_ARRAY); - ::glEnableClientState(GL_NORMAL_ARRAY); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); GLint current_program_id; - ::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id); + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; GLint z_range_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "z_range") : -1; GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1; @@ -742,13 +763,13 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool GLint print_box_worldmatrix_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1; if (print_box_min_id != -1) - ::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min); + glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min)); if (print_box_max_id != -1) - ::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max); + glsafe(::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max)); if (z_range_id != -1) - ::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range); + glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range)); GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func); for (GLVolumeWithZ& volume : to_render) { @@ -756,29 +777,29 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id); } - ::glBindBuffer(GL_ARRAY_BUFFER, 0); - ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - ::glDisableClientState(GL_VERTEX_ARRAY); - ::glDisableClientState(GL_NORMAL_ARRAY); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); if (disable_cullface) - ::glEnable(GL_CULL_FACE); + glsafe(::glEnable(GL_CULL_FACE)); - ::glDisable(GL_BLEND); + glsafe(::glDisable(GL_BLEND)); } void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface) const { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glsafe(glEnable(GL_BLEND)); + glsafe(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - glCullFace(GL_BACK); + glsafe(glCullFace(GL_BACK)); if (disable_cullface) - ::glDisable(GL_CULL_FACE); + glsafe(::glDisable(GL_CULL_FACE)); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); + glsafe(glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(glEnableClientState(GL_NORMAL_ARRAY)); GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, std::function()); for (GLVolumeWithZ& volume : to_render) @@ -787,13 +808,13 @@ void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface) volume.first->render_legacy(); } - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + glsafe(glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(glDisableClientState(GL_NORMAL_ARRAY)); if (disable_cullface) - ::glEnable(GL_CULL_FACE); + glsafe(::glEnable(GL_CULL_FACE)); - glDisable(GL_BLEND); + glsafe(glDisable(GL_BLEND)); } bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state) @@ -1718,44 +1739,44 @@ void GLModel::render() const void GLModel::render_VBOs() const { - ::glEnable(GL_BLEND); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - ::glCullFace(GL_BACK); - ::glEnableClientState(GL_VERTEX_ARRAY); - ::glEnableClientState(GL_NORMAL_ARRAY); + glsafe(::glCullFace(GL_BACK)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); GLint current_program_id; - ::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id); + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; m_volume.render_VBOs(color_id, -1, -1); - ::glBindBuffer(GL_ARRAY_BUFFER, 0); - ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - ::glDisableClientState(GL_VERTEX_ARRAY); - ::glDisableClientState(GL_NORMAL_ARRAY); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - ::glDisable(GL_BLEND); + glsafe(::glDisable(GL_BLEND)); } void GLModel::render_legacy() const { - ::glEnable(GL_LIGHTING); - ::glEnable(GL_BLEND); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - ::glCullFace(GL_BACK); - ::glEnableClientState(GL_VERTEX_ARRAY); - ::glEnableClientState(GL_NORMAL_ARRAY); + glsafe(::glCullFace(GL_BACK)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); m_volume.render_legacy(); - ::glDisableClientState(GL_VERTEX_ARRAY); - ::glDisableClientState(GL_NORMAL_ARRAY); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - ::glDisable(GL_BLEND); - ::glDisable(GL_LIGHTING); + glsafe(::glDisable(GL_BLEND)); + glsafe(::glDisable(GL_LIGHTING)); } bool GLArrow::on_init(bool useVBOs) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index e9340bd6e..7430ff4aa 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -11,6 +11,19 @@ #include +#ifndef NDEBUG +#define HAS_GLSAFE +#endif + +#ifdef HAS_GLSAFE +extern void glAssertRecentCallImpl(); +inline void glAssertRecentCall() { glAssertRecentCallImpl(); } +#define glsafe(cmd) do { cmd; glAssertRecentCallImpl(); } while (false) +#else +inline void glAssertRecentCall() { } +#define glsafe(cmd) cmd +#endif + namespace Slic3r { class Print;