From e291172e2462633b686adf1b217fcaa8da54de97 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 29 Jan 2019 15:11:29 +0100 Subject: [PATCH 01/25] 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 57bd0889c384b4a2420adbfa306de8c8d191b9b4 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 29 Jan 2019 18:07:45 +0100 Subject: [PATCH 02/25] 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 03/25] 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 04/25] 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 05/25] 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 06/25] 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 07/25] 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 08/25] 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 09/25] 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 10/25] 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 11/25] 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 12/25] 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 13/25] 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 14/25] 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 15/25] 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 16/25] 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 17/25] 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 18/25] 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; From 85f7d28c6f0daa493c49e156d66d26e6308647a3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Jan 2019 10:50:16 +0100 Subject: [PATCH 19/25] Added call to _set_current() into GLCanvas3D::on_mouse() --- 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 0a6dd52c0..13c72b945 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5206,6 +5206,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) Point pos(evt.GetX(), evt.GetY()); + if (m_picking_enabled) + _set_current(); + int selected_object_idx = m_selection.get_object_idx(); int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1; m_layers_editing.select_object(*m_model, layer_editing_object_idx); From 81c621716b451f3a2065142967d62e2e8134b6b0 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Jan 2019 13:19:26 +0100 Subject: [PATCH 20/25] User mode-aware toolbar items --- src/libslic3r/Technologies.hpp | 9 +++ src/slic3r/GUI/GLCanvas3D.cpp | 14 ++++ src/slic3r/GUI/GLCanvas3D.hpp | 4 ++ src/slic3r/GUI/GLToolbar.cpp | 128 ++++++++++++++++++++------------- src/slic3r/GUI/GLToolbar.hpp | 32 ++++++--- src/slic3r/GUI/GUI_Preview.cpp | 8 +++ src/slic3r/GUI/GUI_Preview.hpp | 3 + src/slic3r/GUI/Plater.cpp | 4 ++ 8 files changed, 141 insertions(+), 61 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index be37e1694..b6b69ae27 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -56,3 +56,12 @@ #define ENABLE_ANISOTROPIC_FILTER_ON_BED_TEXTURES (1 && ENABLE_1_42_0_ALPHA4) // Bunch of fixes related to volumes centering #define ENABLE_VOLUMES_CENTERING_FIXES (1 && ENABLE_1_42_0_ALPHA4) + + +//==================== +// 1.42.0.alpha5 techs +//==================== +#define ENABLE_1_42_0_ALPHA5 1 + +// Toolbar items hidden/shown in dependence of the user mode +#define ENABLE_MODE_AWARE_TOOLBAR_ITEMS (1 && ENABLE_1_42_0_ALPHA5) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 0a6dd52c0..56e499376 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4414,6 +4414,16 @@ void GLCanvas3D::update_volumes_colors_by_extruder() m_volumes.update_colors_by_extruder(m_config); } +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS +void GLCanvas3D::update_toolbar_items_visibility() +{ + ConfigOptionMode mode = wxGetApp().get_mode(); + m_toolbar.set_item_visible("more", mode != comSimple); + m_toolbar.set_item_visible("fewer", mode != comSimple); + m_dirty = true; +} +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + // Returns a Rect object denoting size and position of the Reset button used by a gizmo. // Returns in either screen or viewport coords. #if !ENABLE_IMGUI @@ -6166,6 +6176,10 @@ bool GLCanvas3D::_init_toolbar() enable_toolbar_item("add", true); +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + update_toolbar_items_visibility(); +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + return true; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 7d38e5128..cbc5013ea 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -1004,6 +1004,10 @@ public: void update_volumes_colors_by_extruder(); +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + void update_toolbar_items_visibility(); +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + #if !ENABLE_IMGUI Rect get_gizmo_reset_rect(const GLCanvas3D& canvas, bool viewport) const; bool gizmo_reset_rect_contains(const GLCanvas3D& canvas, float x, float y) const; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index b15048ec6..8d04868f8 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -35,6 +35,9 @@ GLToolbarItem::Data::Data() , tooltip("") , sprite_id(-1) , is_toggable(false) +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + , visible(true) +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS { } @@ -45,61 +48,11 @@ GLToolbarItem::GLToolbarItem(GLToolbarItem::EType type, const GLToolbarItem::Dat { } -GLToolbarItem::EState GLToolbarItem::get_state() const -{ - return m_state; -} - -void GLToolbarItem::set_state(GLToolbarItem::EState state) -{ - m_state = state; -} - -const std::string& GLToolbarItem::get_name() const -{ - return m_data.name; -} - -const std::string& GLToolbarItem::get_tooltip() const -{ - return m_data.tooltip; -} - void GLToolbarItem::do_action(wxEvtHandler *target) { wxPostEvent(target, SimpleEvent(m_data.action_event)); } -bool GLToolbarItem::is_enabled() const -{ - return m_state != Disabled; -} - -bool GLToolbarItem::is_disabled() const -{ - return m_state == Disabled; -} - -bool GLToolbarItem::is_hovered() const -{ - return (m_state == Hover) || (m_state == HoverPressed); -} - -bool GLToolbarItem::is_pressed() const -{ - return (m_state == Pressed) || (m_state == HoverPressed); -} - -bool GLToolbarItem::is_toggable() const -{ - return m_data.is_toggable; -} - -bool GLToolbarItem::is_separator() const -{ - return m_type == Separator; -} - void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const { GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(texture_size, border_size, icon_size, gap_size)); @@ -355,6 +308,46 @@ bool GLToolbar::is_item_disabled(const std::string& name) const return false; } +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS +bool GLToolbar::is_item_visible(const std::string& name) const +{ + for (GLToolbarItem* item : m_items) + { + if (item->get_name() == name) + return item->is_visible(); + } + + return false; +} + +void GLToolbar::set_item_visible(const std::string& name, bool visible) +{ + for (GLToolbarItem* item : m_items) + { + if ((item->get_name() == name) && (item->is_visible() != visible)) + { + item->set_visible(visible); + m_layout.dirty = true; + break; + } + } + + // updates separators visibility to avoid having two consecutive + bool any_item_visible = false; + for (GLToolbarItem* item : m_items) + { + if (!item->is_separator()) + any_item_visible |= item->is_visible(); + else + { + item->set_visible(any_item_visible); + any_item_visible = false; + } + } + +} +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent) { if (!m_enabled) @@ -486,6 +479,11 @@ float GLToolbar::get_main_size() const float size = 2.0f * m_layout.border * m_layout.icons_scale; for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) { +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (!m_items[i]->is_visible()) + continue; +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (m_items[i]->is_separator()) size += m_layout.separator_size * m_layout.icons_scale; else @@ -524,6 +522,11 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC for (GLToolbarItem* item : m_items) { +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (!item->is_visible()) + continue; +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (item->is_separator()) left += separator_stride; else @@ -618,6 +621,11 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan for (GLToolbarItem* item : m_items) { +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (!item->is_visible()) + continue; +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (item->is_separator()) top -= separator_stride; else @@ -714,6 +722,11 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 { ++id; +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (!item->is_visible()) + continue; +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (item->is_separator()) left += separator_stride; else @@ -759,6 +772,11 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& { ++id; +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (!item->is_visible()) + continue; +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (item->is_separator()) top -= separator_stride; else @@ -892,6 +910,11 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const // renders icons for (const GLToolbarItem* item : m_items) { +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (!item->is_visible()) + continue; +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (item->is_separator()) left += separator_stride; else @@ -1018,6 +1041,11 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const // renders icons for (const GLToolbarItem* item : m_items) { +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (!item->is_visible()) + continue; +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (item->is_separator()) top -= separator_stride; else diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 37eef5708..951d5e072 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -8,7 +8,6 @@ #include "GLTexture.hpp" #include "Event.hpp" - class wxEvtHandler; namespace Slic3r { @@ -56,6 +55,9 @@ public: unsigned int sprite_id; bool is_toggable; wxEventType action_event; +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + bool visible; +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS Data(); }; @@ -68,21 +70,25 @@ private: public: GLToolbarItem(EType type, const Data& data); - EState get_state() const; - void set_state(EState state); + EState get_state() const { return m_state; } + void set_state(EState state) { m_state = state; } - const std::string& get_name() const; - const std::string& get_tooltip() const; + const std::string& get_name() const { return m_data.name; } + const std::string& get_tooltip() const { return m_data.tooltip; } void do_action(wxEvtHandler *target); - bool is_enabled() const; - bool is_disabled() const; - bool is_hovered() const; - bool is_pressed() const; + bool is_enabled() const { return m_state != Disabled; } + bool is_disabled() const { return m_state == Disabled; } + bool is_hovered() const { return (m_state == Hover) || (m_state == HoverPressed); } + bool is_pressed() const { return (m_state == Pressed) || (m_state == HoverPressed); } - bool is_toggable() const; - bool is_separator() const; + bool is_toggable() const { return m_data.is_toggable; } +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + bool is_visible() const { return m_data.visible; } + void set_visible(bool visible) { m_data.visible = visible; } +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + bool is_separator() const { return m_type == Separator; } void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const; @@ -223,6 +229,10 @@ public: bool is_item_pressed(const std::string& name) const; bool is_item_disabled(const std::string& name) const; +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + bool is_item_visible(const std::string& name) const; + void set_item_visible(const std::string& name, bool visible); +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS std::string update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index b594d0fef..0ad6c3562 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -139,6 +139,14 @@ void View3D::mirror_selection(Axis axis) m_canvas->mirror_selection(axis); } +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS +void View3D::update_toolbar_items_visibility() +{ + if (m_canvas != nullptr) + m_canvas->update_toolbar_items_visibility(); +} +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS + void View3D::enable_toolbar_item(const std::string& name, bool enable) { if (m_canvas != nullptr) diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index d4410c589..49dbed44d 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -58,6 +58,9 @@ public: void delete_selected(); void mirror_selection(Axis axis); +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + void update_toolbar_items_visibility(); +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS void enable_toolbar_item(const std::string& name, bool enable); int check_volumes_outside_state() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4902cf1c9..38adde8b3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2648,6 +2648,10 @@ bool Plater::priv::can_mirror() const void Plater::priv::update_object_menu() { sidebar->obj_list()->append_menu_items_add_volume(&object_menu); +#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS + if (view3D != nullptr) + view3D->update_toolbar_items_visibility(); +#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS } // Plater / Public From 1605c23e259ff8c90c3ca798dc2cf72b53efd4d3 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 31 Jan 2019 13:21:17 +0100 Subject: [PATCH 21/25] Updated KBShortcutsDialog --- src/slic3r/GUI/KBShortcutsDialog.cpp | 41 ++++++++++++++++++++++++---- src/slic3r/GUI/KBShortcutsDialog.hpp | 4 +-- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 23169dde1..3aeda0348 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -44,7 +44,8 @@ KBShortcutsDialog::KBShortcutsDialog() for (auto& sc : m_full_shortcuts) { - auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer; +// auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer; + auto sizer = sc.second.second == 0 ? l_sizer : r_sizer; wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10); @@ -61,7 +62,7 @@ KBShortcutsDialog::KBShortcutsDialog() auto grid_sizer = new wxFlexGridSizer(2, 5, 15); sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT| wxRIGHT, 15); - for (auto pair : sc.second) + for (auto pair : sc.second.first) { auto shortcut = new wxStaticText(panel, wxID_ANY, _(pair.first)); shortcut->SetFont(bold_font); @@ -95,6 +96,8 @@ void KBShortcutsDialog::fill_shortcuts() const std::string alt = "Alt+"; #endif // __WXOSX__ + m_full_shortcuts.reserve(4); + Shortcuts main_shortcuts; main_shortcuts.reserve(25); @@ -122,7 +125,7 @@ void KBShortcutsDialog::fill_shortcuts() main_shortcuts.push_back(Shortcut("?" ,L("Show keyboard shortcuts list"))); main_shortcuts.push_back(Shortcut("Shift+LeftMouse", L("Select multiple object/Move multiple object"))); - m_full_shortcuts.emplace(_(L("Main Shortcuts")), main_shortcuts); + m_full_shortcuts.push_back(std::make_pair( _(L("Main Shortcuts")), std::make_pair(main_shortcuts, 0) )); Shortcuts plater_shortcuts; @@ -138,6 +141,8 @@ void KBShortcutsDialog::fill_shortcuts() plater_shortcuts.push_back(Shortcut("C", L("Gizmo cut"))); plater_shortcuts.push_back(Shortcut("F", L("Gizmo Place face on bed"))); plater_shortcuts.push_back(Shortcut("L", L("Gizmo SLA support points"))); + plater_shortcuts.push_back(Shortcut("Shift+", L("Press to snap by 5% in Gizmo scale\nor by 1mm in Gizmo move"))); + plater_shortcuts.push_back(Shortcut(alt, L("Press to scale or rotate selected objects\naround their own center"))); plater_shortcuts.push_back(Shortcut("B", L("Zoom to Bed"))); plater_shortcuts.push_back(Shortcut("Z", L("Zoom to all objects in scene, if none selected"))); plater_shortcuts.push_back(Shortcut("Z", L("Zoom to selected object"))); @@ -145,16 +150,40 @@ void KBShortcutsDialog::fill_shortcuts() plater_shortcuts.push_back(Shortcut("O", L("Zoom out"))); plater_shortcuts.push_back(Shortcut("ESC", L("Unselect gizmo, keep object selection"))); - m_full_shortcuts.emplace(_(L("Plater Shortcuts")), plater_shortcuts); + m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, 1))); + + +// Shortcuts gizmo_shortcuts; +// gizmo_shortcuts.reserve(2); +// +// gizmo_shortcuts.push_back(Shortcut("Shift+", L("Press to snap by 5% in Gizmo Scale\n or by 1mm in Gizmo Move"))); +// gizmo_shortcuts.push_back(Shortcut(alt, L("Press to scale or rotate selected objects around their own center"))); +// +// m_full_shortcuts.push_back(std::make_pair(_(L("Gizmo Shortcuts")), std::make_pair(gizmo_shortcuts, 1))); Shortcuts preview_shortcuts; - preview_shortcuts.reserve(2); + preview_shortcuts.reserve(4); preview_shortcuts.push_back(Shortcut(L("Arrow Up"), L("Upper Layer"))); preview_shortcuts.push_back(Shortcut(L("Arrow Down"), L("Lower Layer"))); + preview_shortcuts.push_back(Shortcut("U", L("Upper Layer"))); + preview_shortcuts.push_back(Shortcut("D", L("Lower Layer"))); - m_full_shortcuts.emplace(_(L("Preview Shortcuts")), preview_shortcuts); + m_full_shortcuts.push_back(std::make_pair( _(L("Preview Shortcuts")), std::make_pair(preview_shortcuts, 0) )); + + + Shortcuts layers_slider_shortcuts; + layers_slider_shortcuts.reserve(6); + + layers_slider_shortcuts.push_back(Shortcut(L("Arrow Up"), L("Move current slider thump Up"))); + layers_slider_shortcuts.push_back(Shortcut(L("Arrow Down"), L("Move current slider thump Down"))); + layers_slider_shortcuts.push_back(Shortcut(L("Arrow Left"), L("Set upper thumb to current slider thumb"))); + layers_slider_shortcuts.push_back(Shortcut(L("Arrow Right"),L("Set lower thumb to current slider thumb"))); + layers_slider_shortcuts.push_back(Shortcut("+", L("Add color change marker for current layer"))); + layers_slider_shortcuts.push_back(Shortcut("-", L("Delete color change marker for current layer"))); + + m_full_shortcuts.push_back(std::make_pair( _(L("Layers Slider Shortcuts")), std::make_pair(layers_slider_shortcuts, 1) )); } void KBShortcutsDialog::onCloseDialog(wxEvent &) diff --git a/src/slic3r/GUI/KBShortcutsDialog.hpp b/src/slic3r/GUI/KBShortcutsDialog.hpp index 8517544b5..c5f60f0b8 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.hpp +++ b/src/slic3r/GUI/KBShortcutsDialog.hpp @@ -11,11 +11,11 @@ class KBShortcutsDialog : public wxDialog { typedef std::pair Shortcut; typedef std::vector< Shortcut > Shortcuts; - typedef std::map ShortcutsMap; + typedef std::vector< std::pair> > ShortcutsVec; wxString text_info {wxEmptyString}; - ShortcutsMap m_full_shortcuts; + ShortcutsVec m_full_shortcuts; public: KBShortcutsDialog(); From fb6ef1d20fdfaecef3f3b4792386acd6a31f58b5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Jan 2019 14:25:11 +0100 Subject: [PATCH 22/25] Keeps modifier transparent while layer editing tool is enabled --- src/slic3r/GUI/3DScene.cpp | 4 ++++ src/slic3r/GUI/3DScene.hpp | 2 ++ src/slic3r/GUI/GLCanvas3D.cpp | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index fd1645c9e..6b1df6ab3 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -252,6 +252,7 @@ GLVolume::GLVolume(float r, float g, float b, float a) , is_modifier(false) , is_wipe_tower(false) , is_extrusion_path(false) + , force_transparent(false) , tverts_range(0, size_t(-1)) , qverts_range(0, size_t(-1)) { @@ -293,6 +294,9 @@ void GLVolume::set_render_color() set_render_color(OUTSIDE_COLOR, 4); else set_render_color(color, 4); + + if (force_transparent) + render_color[3] = color[3]; } void GLVolume::set_color_from_model_volume(const ModelVolume *model_volume) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 7430ff4aa..2732b5a13 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -295,6 +295,8 @@ public: bool is_wipe_tower; // Wheter or not this volume has been generated from an extrusion path bool is_extrusion_path; + // Wheter or not to always render this volume using its own alpha + bool force_transparent; // Interleaved triangles & normals with indexed triangles & quads. GLIndexedVertexArray indexed_vertex_array; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 72dfe52bd..33f62f205 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4286,6 +4286,13 @@ bool GLCanvas3D::is_reload_delayed() const void GLCanvas3D::enable_layers_editing(bool enable) { m_layers_editing.set_enabled(enable); + const Selection::IndicesList& idxs = m_selection.get_volume_idxs(); + for (unsigned int idx : idxs) + { + GLVolume* v = m_volumes.volumes[idx]; + if (v->is_modifier) + v->force_transparent = enable; + } } void GLCanvas3D::enable_warning_texture(bool enable) From c82d346c1a5b119aeb8c5176f832ccf19e7dbd9f Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 31 Jan 2019 15:09:16 +0100 Subject: [PATCH 23/25] Fixed a bug in initialization of some StaticPrintConfig derived classes. Merged implementation of support for "Octoprint-Cancelobject" #972 thanks @supermerill --- src/libslic3r/GCode.cpp | 6 +++++- src/libslic3r/Print.cpp | 1 + src/libslic3r/PrintConfig.cpp | 9 +++++++++ src/libslic3r/PrintConfig.hpp | 6 ++++-- src/slic3r/GUI/Preset.cpp | 4 ++-- src/slic3r/GUI/Tab.cpp | 1 + 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 66698d4ad..ec9392ec4 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1622,6 +1622,8 @@ void GCode::process_layer( unsigned int copy_id = 0; for (const Point © : copies) { + if (this->config().gcode_label_objects) + gcode += std::string("; printing object ") + print_object->model_object()->name + " id:" + std::to_string(layer_id) + " copy " + std::to_string(copy_id) + "\n"; // When starting a new object, use the external motion planner for the first travel move. std::pair this_object_copy(print_object, copy); if (m_last_obj_copy != this_object_copy) @@ -1646,7 +1648,9 @@ void GCode::process_layer( gcode += this->extrude_infill(print,by_region_specific); } } - ++copy_id; + if (this->config().gcode_label_objects) + gcode += std::string("; stop printing object ") + print_object->model_object()->name + " id:" + std::to_string(layer_id) + " copy " + std::to_string(copy_id) + "\n"; + ++ copy_id; } } } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 3efb18599..42fda92fe 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -127,6 +127,7 @@ bool Print::invalidate_state_by_config_options(const std::vectormode = comExpert; def->default_value = new ConfigOptionEnum(gcfRepRap); + def = this->add("gcode_label_objects", coBool); + def->label = "Label objects"; + def->tooltip = "Enable this to add comments into the G-Code labeling print moves with what object they belong to," + " which is useful for the Octoprint CancelObject plugin. This settings is NOT compatible with " + "Single Extruder Multi Material setup and Wipe into Object / Wipe into Infill."; + def->cli = "gcode-label-objects!"; + def->mode = comAdvanced; + def->default_value = new ConfigOptionBool(0); + def = this->add("high_current_on_filament_swap", coBool); def->label = L("High extruder current on filament swap"); def->tooltip = L("It may be beneficial to increase the extruder motor current during the filament exchange" diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 1b218a192..6b9e68eef 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -619,6 +619,7 @@ public: ConfigOptionStrings filament_ramming_parameters; ConfigOptionBool gcode_comments; ConfigOptionEnum gcode_flavor; + ConfigOptionBool gcode_label_objects; ConfigOptionString layer_gcode; ConfigOptionFloat max_print_speed; ConfigOptionFloat max_volumetric_speed; @@ -690,6 +691,7 @@ protected: OPT_PTR(filament_ramming_parameters); OPT_PTR(gcode_comments); OPT_PTR(gcode_flavor); + OPT_PTR(gcode_label_objects); OPT_PTR(layer_gcode); OPT_PTR(max_print_speed); OPT_PTR(max_volumetric_speed); @@ -730,7 +732,7 @@ protected: class PrintConfig : public MachineEnvelopeConfig, public GCodeConfig { STATIC_PRINT_CONFIG_CACHE_DERIVED(PrintConfig) - PrintConfig() : GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); } + PrintConfig() : MachineEnvelopeConfig(0), GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); } public: double min_object_distance() const; static double min_object_distance(const ConfigBase *config); @@ -808,7 +810,7 @@ public: ConfigOptionFloat exp_time_first; protected: - PrintConfig(int) : GCodeConfig(1) {} + PrintConfig(int) : MachineEnvelopeConfig(1), GCodeConfig(1) {} void initialize(StaticCacheBase &cache, const char *base_ptr) { this->MachineEnvelopeConfig::initialize(cache, base_ptr); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index ef1caf035..53650481c 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -336,7 +336,7 @@ const std::vector& Preset::print_options() "support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance", "support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius", - "extruder_clearance_height", "gcode_comments", "output_filename_format", "post_process", "perimeter_extruder", + "extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder", "infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder", "ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width", "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", @@ -1163,7 +1163,7 @@ std::string PresetCollection::name() const case Preset::TYPE_PRINT: return L("print"); case Preset::TYPE_FILAMENT: return L("filament"); case Preset::TYPE_SLA_PRINT: return L("SLA print"); - case Preset::TYPE_SLA_MATERIAL: return L("SLA material"); + case Preset::TYPE_SLA_MATERIAL: return L("SLA material"); case Preset::TYPE_PRINTER: return L("printer"); default: return "invalid"; } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 3f76b4f78..06282cd24 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1095,6 +1095,7 @@ void TabPrint::build() optgroup = page->new_optgroup(_(L("Output file"))); optgroup->append_single_option_line("gcode_comments"); + optgroup->append_single_option_line("gcode_label_objects"); option = optgroup->get_option("output_filename_format"); option.opt.full_width = true; optgroup->append_single_option_line(option); From 405d18a7fab4a7a0b0eefda531f232fecb9ec7ea Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 1 Feb 2019 08:53:29 +0100 Subject: [PATCH 24/25] Changed default the Drag & Drop target from "Move" to "Copy". Fixes #1742 --- src/slic3r/GUI/Plater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 38adde8b3..428ea07c6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -896,7 +896,7 @@ std::vector& Sidebar::combos_filament() class PlaterDropTarget : public wxFileDropTarget { public: - PlaterDropTarget(Plater *plater) : plater(plater) {} + PlaterDropTarget(Plater *plater) : plater(plater) { this->SetDefaultAction(wxDragCopy); } virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames); From 3b973e01dd3c893116d80ba79cb8f06ff023cce5 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 1 Feb 2019 11:44:08 +0100 Subject: [PATCH 25/25] Get name of both the G-code and project file from the 1st printable object's name or file path. Fixed some compilation warnings. --- src/libslic3r/GCode/SpiralVase.hpp | 2 +- src/libslic3r/GCodeReader.hpp | 2 +- src/libslic3r/Model.cpp | 13 ++++++++++--- src/libslic3r/PrintBase.cpp | 15 ++------------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/GCode/SpiralVase.hpp b/src/libslic3r/GCode/SpiralVase.hpp index 60aa668d8..7872b1d3c 100644 --- a/src/libslic3r/GCode/SpiralVase.hpp +++ b/src/libslic3r/GCode/SpiralVase.hpp @@ -13,7 +13,7 @@ class SpiralVase { SpiralVase(const PrintConfig &config) : enable(false), _config(&config) { - this->_reader.z() = this->_config->z_offset; + this->_reader.z() = (float)this->_config->z_offset; this->_reader.apply_config(*this->_config); }; std::string process_layer(const std::string &gcode); diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index 13f9e7dd7..f64605a9c 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -43,7 +43,7 @@ public: } bool cmd_is(const char *cmd_test) const { const char *cmd = GCodeReader::skip_whitespaces(m_raw.c_str()); - int len = strlen(cmd_test); + size_t len = strlen(cmd_test); return strncmp(cmd, cmd_test, len) == 0 && GCodeReader::is_end_of_word(cmd[len]); } bool extruding(const GCodeReader &reader) const { return this->cmd_is("G1") && this->dist_E(reader) > 0; } diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index a88bdd991..968a3e234 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -549,11 +549,18 @@ void Model::reset_auto_extruder_id() std::string Model::propose_export_file_name() const { + std::string input_file; for (const ModelObject *model_object : this->objects) for (ModelInstance *model_instance : model_object->instances) - if (model_instance->is_printable()) - return model_object->name.empty() ? model_object->input_file : model_object->name; - return std::string(); + if (model_instance->is_printable()) { + input_file = model_object->name.empty() ? model_object->input_file : model_object->name; + if (! input_file.empty()) + goto end; + // Other instances will produce the same name, skip them. + break; + } +end: + return input_file; } ModelObject::~ModelObject() diff --git a/src/libslic3r/PrintBase.cpp b/src/libslic3r/PrintBase.cpp index 1d078da30..48e991b8d 100644 --- a/src/libslic3r/PrintBase.cpp +++ b/src/libslic3r/PrintBase.cpp @@ -67,20 +67,9 @@ std::string PrintBase::output_filename(const std::string &format, const std::str std::string PrintBase::output_filepath(const std::string &path) const { // if we were supplied no path, generate an automatic one based on our first object's input file - if (path.empty()) { + if (path.empty()) // get the first input file name - std::string input_file; - for (const ModelObject *model_object : m_model.objects) { - for (ModelInstance *model_instance : model_object->instances) - if (model_instance->is_printable()) { - input_file = model_object->input_file; - break; - } - if (! input_file.empty()) - break; - } - return (boost::filesystem::path(input_file).parent_path() / this->output_filename()).make_preferred().string(); - } + return (boost::filesystem::path(m_model.propose_export_file_name()).parent_path() / this->output_filename()).make_preferred().string(); // if we were supplied a directory, use it and append our automatically generated filename boost::filesystem::path p(path);