From fd3d673a1ebf72b923f394e5788e1fdefe8a370c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 6 Sep 2021 12:18:46 +0200 Subject: [PATCH 01/27] Tech ENABLE_PREVIEW_LAYER_TIME - Implementation of coloring toolpaths by layer time (Similar to pull request #3904) --- src/libslic3r/Technologies.hpp | 9 +++ src/libslic3r/Utils.hpp | 3 +- src/slic3r/GUI/GCodeViewer.cpp | 103 ++++++++++++++++++++++++++++----- src/slic3r/GUI/GCodeViewer.hpp | 38 ++++++++---- src/slic3r/GUI/GUI_Preview.cpp | 3 + 5 files changed, 127 insertions(+), 29 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 6132430f1a..fd7609e770 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -57,4 +57,13 @@ #define ENABLE_SAVE_COMMANDS_ALWAYS_ENABLED (1 && ENABLE_2_4_0_ALPHA0) +//==================== +// 2.4.0.alpha2 techs +//==================== +#define ENABLE_2_4_0_ALPHA2 1 + +// Enable coloring of toolpaths in preview by layer time +#define ENABLE_PREVIEW_LAYER_TIME (1 && ENABLE_2_4_0_ALPHA2) + + #endif // _prusaslicer_technologies_h_ diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index a01e63166b..d4f53013f8 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -343,7 +344,7 @@ inline std::string get_time_dhms(float time_in_secs) else if (minutes > 0) ::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs); else - ::sprintf(buffer, "%ds", (int)time_in_secs); + ::sprintf(buffer, "%ds", (int)std::round(time_in_secs)); return buffer; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 656a674066..d909f8ac23 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -730,6 +730,18 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } } +#if ENABLE_PREVIEW_LAYER_TIME + for (size_t i = 0; i < gcode_result.print_statistics.modes.size(); ++i) { + m_layers_times[i] = gcode_result.print_statistics.modes[i].layers_times; + } + + for (size_t i = 0; i < m_layers_times.size(); ++i) { + for (float time : m_layers_times[i]) { + m_extrusions.ranges.layer_time[i].update_from(time); + } + } +#endif // ENABLE_PREVIEW_LAYER_TIME + #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -771,6 +783,11 @@ void GCodeViewer::reset() m_layers_z_range = { 0, 0 }; m_roles = std::vector(); m_print_statistics.reset(); +#if ENABLE_PREVIEW_LAYER_TIME + for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { + m_layers_times[i] = std::vector(); + } +#endif // ENABLE_PREVIEW_LAYER_TIME #if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER m_custom_gcode_per_print_z = std::vector(); #endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER @@ -1965,7 +1982,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (last_z == nullptr || z < *last_z - EPSILON || *last_z + EPSILON < z) m_layers.append(z, { last_travel_s_id, i }); else - m_layers.get_endpoints().back().last = i; + m_layers.get_ranges().back().last = i; // extruder ids m_extruder_ids.emplace_back(move.extruder_id); // roles @@ -1974,7 +1991,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } else if (move.type == EMoveType::Travel) { if (i - last_travel_s_id > 1 && !m_layers.empty()) - m_layers.get_endpoints().back().last = i; + m_layers.get_ranges().back().last = i; last_travel_s_id = i; } @@ -2082,6 +2099,24 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } case EViewType::Temperature: { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; } +#if ENABLE_PREVIEW_LAYER_TIME + case EViewType::LayerTime: { + const Path::Sub_Path& sub_path = path.sub_paths.front(); + double z = static_cast(sub_path.first.position.z()); + const std::vector& zs = m_layers.get_zs(); + const std::vector& ranges = m_layers.get_ranges(); + size_t time_mode_id = static_cast(m_time_estimate_mode); + for (size_t i = 0; i < zs.size(); ++i) { + if (std::abs(zs[i] - z) < EPSILON) { + if (ranges[i].contains(sub_path.first.s_id)) { + color = m_extrusions.ranges.layer_time[time_mode_id].get_color_at(m_layers_times[time_mode_id][i]); + break; + } + } + } + break; + } +#endif // ENABLE_PREVIEW_LAYER_TIME case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } case EViewType::ColorPrint: { @@ -2106,7 +2141,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool auto is_in_layers_range = [this](const Path& path, size_t min_id, size_t max_id) { auto in_layers_range = [this, min_id, max_id](size_t id) { - return m_layers.get_endpoints_at(min_id).first <= id && id <= m_layers.get_endpoints_at(max_id).last; + return m_layers.get_range_at(min_id).first <= id && id <= m_layers.get_range_at(max_id).last; }; return in_layers_range(path.sub_paths.front().first.s_id) || in_layers_range(path.sub_paths.back().last.s_id); @@ -2131,8 +2166,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool path.sub_paths.back().last = buffer.paths[last].sub_paths.back().last; } - const size_t min_s_id = m_layers.get_endpoints_at(min_id).first; - const size_t max_s_id = m_layers.get_endpoints_at(max_id).last; + const size_t min_s_id = m_layers.get_range_at(min_id).first; + const size_t max_s_id = m_layers.get_range_at(max_id).last; return (min_s_id <= path.sub_paths.front().first.s_id && path.sub_paths.front().first.s_id <= max_s_id) || (min_s_id <= path.sub_paths.back().last.s_id && path.sub_paths.back().last.s_id <= max_s_id); @@ -2167,14 +2202,14 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool #if ENABLE_SEAMS_USING_MODELS if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) { for (size_t id : buffer.model.instances.s_ids) { - if (id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id) + if (id < m_layers.get_range_at(m_layers_z_range[0]).first || m_layers.get_range_at(m_layers_z_range[1]).last < id) continue; global_endpoints.first = std::min(global_endpoints.first, id); global_endpoints.last = std::max(global_endpoints.last, id); if (top_layer_only) { - if (id < m_layers.get_endpoints_at(m_layers_z_range[1]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id) + if (id < m_layers.get_range_at(m_layers_z_range[1]).first || m_layers.get_range_at(m_layers_z_range[1]).last < id) continue; top_layer_endpoints.first = std::min(top_layer_endpoints.first, id); @@ -2847,8 +2882,13 @@ void GCodeViewer::render_legend(float& legend_height) }; const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast(m_time_estimate_mode)]; +#if ENABLE_PREVIEW_LAYER_TIME + bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || m_view_type == EViewType::LayerTime || + (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty())); +#else bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty())); +#endif // ENABLE_PREVIEW_LAYER_TIME const float icon_size = ImGui::GetTextLineHeight(); const float percent_bar_size = 2.0f * ImGui::GetTextLineHeight(); @@ -2971,6 +3011,7 @@ void GCodeViewer::render_legend(float& legend_height) // single item use case append_range_item(0, range.min, decimals); else if (range.count == 2) { + // two items use case append_range_item(static_cast(Range_Colors.size()) - 1, range.max, decimals); append_range_item(0, range.min, decimals); } @@ -2982,6 +3023,29 @@ void GCodeViewer::render_legend(float& legend_height) } }; +#if ENABLE_PREVIEW_LAYER_TIME + auto append_time_range = [append_item](const Extrusions::Range& range) { + auto append_range_item = [append_item](int i, float value) { + append_item(EItemType::Rect, Range_Colors[i], get_time_dhms(value)); + }; + + if (range.count == 1) + // single item use case + append_range_item(0, range.min); + else if (range.count == 2) { + // two items use case + append_range_item(static_cast(Range_Colors.size()) - 1, range.max); + append_range_item(0, range.min); + } + else { + const float step_size = range.step_size(); + for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) { + append_range_item(i, range.min + static_cast(i) * step_size); + } + } + }; +#endif // ENABLE_PREVIEW_LAYER_TIME + auto append_headers = [&imgui](const std::array& texts, const std::array& offsets) { size_t i = 0; for (; i < offsets.size(); i++) { @@ -3163,8 +3227,10 @@ void GCodeViewer::render_legend(float& legend_height) case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; } case EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; } case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } - case EViewType::Tool: - { +#if ENABLE_PREVIEW_LAYER_TIME + case EViewType::LayerTime: { imgui.title(_u8L("Layer time")); break; } +#endif // ENABLE_PREVIEW_LAYER_TIME + case EViewType::Tool: { append_headers({ _u8L("Tool"), _u8L("Used filament") }, offsets); break; } @@ -3186,7 +3252,7 @@ void GCodeViewer::render_legend(float& legend_height) visible, times[i], percents[i], max_percent, offsets, used_filaments_m[i], used_filaments_g[i], [this, role, visible]() { m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths - refresh_render_paths(false, false); + refresh_render_paths(); wxGetApp().plater()->update_preview_moves_slider(); wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->update_preview_bottom_toolbar(); @@ -3201,8 +3267,10 @@ void GCodeViewer::render_legend(float& legend_height) case EViewType::FanSpeed: { append_range(m_extrusions.ranges.fan_speed, 0); break; } case EViewType::Temperature: { append_range(m_extrusions.ranges.temperature, 0); break; } case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; } - case EViewType::Tool: - { +#if ENABLE_PREVIEW_LAYER_TIME + case EViewType::LayerTime: { append_time_range(m_extrusions.ranges.layer_time[static_cast(m_time_estimate_mode)]); break; } +#endif // ENABLE_PREVIEW_LAYER_TIME + case EViewType::Tool: { // shows only extruders actually used size_t i = 0; for (unsigned char extruder_id : m_extruder_ids) { @@ -3212,8 +3280,7 @@ void GCodeViewer::render_legend(float& legend_height) } break; } - case EViewType::ColorPrint: - { + case EViewType::ColorPrint: { #if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER const std::vector& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z; #else @@ -3626,7 +3693,7 @@ void GCodeViewer::render_legend(float& legend_height) if (can_show_mode_button(m_time_estimate_mode)) { switch (m_time_estimate_mode) { - case PrintEstimatedStatistics::ETimeMode::Normal: { time_title += " [" + _u8L("Normal mode") + "]"; break; } + case PrintEstimatedStatistics::ETimeMode::Normal: { time_title += " [" + _u8L("Normal mode") + "]"; break; } case PrintEstimatedStatistics::ETimeMode::Stealth: { time_title += " [" + _u8L("Stealth mode") + "]"; break; } default: { assert(false); break; } } @@ -3657,6 +3724,10 @@ void GCodeViewer::render_legend(float& legend_height) if (can_show_mode_button(mode)) { if (imgui.button(label)) { m_time_estimate_mode = mode; +#if ENABLE_PREVIEW_LAYER_TIME + if (m_view_type == EViewType::LayerTime) + refresh_render_paths(); +#endif // ENABLE_PREVIEW_LAYER_TIME wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); } @@ -3803,7 +3874,7 @@ void GCodeViewer::log_memory_used(const std::string& label, int64_t additional) } } int64_t layers_size = SLIC3R_STDVEC_MEMSIZE(m_layers.get_zs(), double); - layers_size += SLIC3R_STDVEC_MEMSIZE(m_layers.get_endpoints(), Layers::Endpoints); + layers_size += SLIC3R_STDVEC_MEMSIZE(m_layers.get_ranges(), Layers::Range); BOOST_LOG_TRIVIAL(trace) << label << "(" << format_memsize_MB(additional + paths_size + render_paths_size + layers_size) << ");" << log_memory_info(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 429175fe68..73bdb0ac0e 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -417,6 +417,10 @@ class GCodeViewer Range volumetric_rate; // Color mapping by extrusion temperature. Range temperature; +#if ENABLE_PREVIEW_LAYER_TIME + // Color mapping by layer time. + std::array(PrintEstimatedStatistics::ETimeMode::Count)> layer_time; +#endif // ENABLE_PREVIEW_LAYER_TIME void reset() { height.reset(); @@ -425,6 +429,11 @@ class GCodeViewer fan_speed.reset(); volumetric_rate.reset(); temperature.reset(); +#if ENABLE_PREVIEW_LAYER_TIME + for (auto& range : layer_time) { + range.reset(); + } +#endif // ENABLE_PREVIEW_LAYER_TIME } }; @@ -444,43 +453,42 @@ class GCodeViewer class Layers { public: - struct Endpoints + struct Range { size_t first{ 0 }; size_t last{ 0 }; - bool operator == (const Endpoints& other) const { - return first == other.first && last == other.last; - } + bool operator == (const Range& other) const { return first == other.first && last == other.last; } + bool contains(size_t id) const { return first <= id && id <= last; } }; private: std::vector m_zs; - std::vector m_endpoints; + std::vector m_ranges; public: - void append(double z, Endpoints endpoints) { + void append(double z, const Range& range) { m_zs.emplace_back(z); - m_endpoints.emplace_back(endpoints); + m_ranges.emplace_back(range); } void reset() { m_zs = std::vector(); - m_endpoints = std::vector(); + m_ranges = std::vector(); } size_t size() const { return m_zs.size(); } bool empty() const { return m_zs.empty(); } const std::vector& get_zs() const { return m_zs; } - const std::vector& get_endpoints() const { return m_endpoints; } - std::vector& get_endpoints() { return m_endpoints; } + const std::vector& get_ranges() const { return m_ranges; } + std::vector& get_ranges() { return m_ranges; } double get_z_at(unsigned int id) const { return (id < m_zs.size()) ? m_zs[id] : 0.0; } - Endpoints get_endpoints_at(unsigned int id) const { return (id < m_endpoints.size()) ? m_endpoints[id] : Endpoints(); } + Range get_range_at(unsigned int id) const { return (id < m_ranges.size()) ? m_ranges[id] : Range(); } bool operator != (const Layers& other) const { if (m_zs != other.m_zs) return true; - if (!(m_endpoints == other.m_endpoints)) + if (!(m_ranges == other.m_ranges)) return true; return false; @@ -692,6 +700,9 @@ public: FanSpeed, Temperature, VolumetricRate, +#if ENABLE_PREVIEW_LAYER_TIME + LayerTime, +#endif // ENABLE_PREVIEW_LAYER_TIME Tool, ColorPrint, Count @@ -727,6 +738,9 @@ private: std::array m_detected_point_sizes = { 0.0f, 0.0f }; GCodeProcessor::Result::SettingsIds m_settings_ids; std::array m_sequential_range_caps; +#if ENABLE_PREVIEW_LAYER_TIME + std::array, static_cast(PrintEstimatedStatistics::ETimeMode::Count)> m_layers_times; +#endif // ENABLE_PREVIEW_LAYER_TIME #if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER std::vector m_custom_gcode_per_print_z; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 8c10fb1576..231fa92067 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -225,6 +225,9 @@ bool Preview::init(wxWindow* parent, Model* model) m_choice_view_type->Append(_L("Fan speed")); m_choice_view_type->Append(_L("Temperature")); m_choice_view_type->Append(_L("Volumetric flow rate")); +#if ENABLE_PREVIEW_LAYER_TIME + m_choice_view_type->Append(_L("Layer time")); +#endif // ENABLE_PREVIEW_LAYER_TIME m_choice_view_type->Append(_L("Tool")); m_choice_view_type->Append(_L("Color Print")); m_choice_view_type->SetSelection(0); From 8f36002ebeb743b71b042f0b55ba56dd46956cd0 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 6 Sep 2021 14:59:22 +0200 Subject: [PATCH 02/27] Tech ENABLE_PREVIEW_LAYER_TIME - Show '< 1s' in place of '0s' in preview legend --- src/slic3r/GUI/GCodeViewer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3d7d754274..2c5ef72a00 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3026,7 +3026,10 @@ void GCodeViewer::render_legend(float& legend_height) #if ENABLE_PREVIEW_LAYER_TIME auto append_time_range = [append_item](const Extrusions::Range& range) { auto append_range_item = [append_item](int i, float value) { - append_item(EItemType::Rect, Range_Colors[i], get_time_dhms(value)); + std::string str_value = get_time_dhms(value); + if (str_value == "0s") + str_value = "< 1s"; + append_item(EItemType::Rect, Range_Colors[i], str_value); }; if (range.count == 1) From f30fffa0bc0d5c4a978d94d2293185bb8e932a31 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 13 Sep 2021 10:05:06 +0200 Subject: [PATCH 03/27] ENABLE_PREVIEW_LAYER_TIME -> Linear and logarithmic layer time visualization --- src/slic3r/GUI/GCodeViewer.cpp | 89 ++++++++++++++++++++++++---------- src/slic3r/GUI/GCodeViewer.hpp | 16 +++++- src/slic3r/GUI/GUI_Preview.cpp | 3 +- 3 files changed, 81 insertions(+), 27 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 966dd60aed..b1483dcdc6 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -179,11 +179,38 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsi move.volumetric_rate(), move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); } +#if ENABLE_PREVIEW_LAYER_TIME +float GCodeViewer::Extrusions::Range::step_size(EType type) const +{ + switch (type) + { + default: + case EType::Linear: { return (max > min) ? (max - min) / (static_cast(Range_Colors.size()) - 1.0f) : 0.0f; } + case EType::Logarithmic: { return (max > min && min > 0.0f) ? ::log(max / min) / (static_cast(Range_Colors.size()) - 1.0f) : 0.0f; } + } +} + +GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value, EType type) const +#else GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) const +#endif // ENABLE_PREVIEW_LAYER_TIME { // Input value scaled to the colors range +#if ENABLE_PREVIEW_LAYER_TIME + float global_t = 0.0f; + const float step = step_size(type); + if (step > 0.0f) { + switch (type) + { + default: + case EType::Linear: { global_t = (value > min) ? (value - min) / step : 0.0f; break; } + case EType::Logarithmic: { global_t = (value > min && min > 0.0f) ? ::log(value / min) / step : 0.0f; break; } + } + } +#else const float step = step_size(); const float global_t = (step != 0.0f) ? std::max(0.0f, value - min) / step : 0.0f; // lower limit of 0.0f +#endif // ENABLE_PREVIEW_LAYER_TIME const size_t color_max_idx = Range_Colors.size() - 1; @@ -2196,7 +2223,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } case EViewType::Temperature: { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; } #if ENABLE_PREVIEW_LAYER_TIME - case EViewType::LayerTime: { + case EViewType::LayerTimeLinear: + case EViewType::LayerTimeLogarithmic: { const Path::Sub_Path& sub_path = path.sub_paths.front(); double z = static_cast(sub_path.first.position.z()); const std::vector& zs = m_layers.get_zs(); @@ -2205,7 +2233,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool for (size_t i = 0; i < zs.size(); ++i) { if (std::abs(zs[i] - z) < EPSILON) { if (ranges[i].contains(sub_path.first.s_id)) { - color = m_extrusions.ranges.layer_time[time_mode_id].get_color_at(m_layers_times[time_mode_id][i]); + color = m_extrusions.ranges.layer_time[time_mode_id].get_color_at(m_layers_times[time_mode_id][i], + (m_view_type == EViewType::LayerTimeLinear) ? Extrusions::Range::EType::Linear : Extrusions::Range::EType::Logarithmic); break; } } @@ -3073,7 +3102,8 @@ void GCodeViewer::render_legend(float& legend_height) const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast(m_time_estimate_mode)]; #if ENABLE_PREVIEW_LAYER_TIME - bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || m_view_type == EViewType::LayerTime || + bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || + m_view_type == EViewType::LayerTimeLinear || m_view_type == EViewType::LayerTimeLogarithmic || (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty())); #else bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || @@ -3216,7 +3246,7 @@ void GCodeViewer::render_legend(float& legend_height) }; #if ENABLE_PREVIEW_LAYER_TIME - auto append_time_range = [append_item](const Extrusions::Range& range) { + auto append_time_range = [append_item](const Extrusions::Range& range, Extrusions::Range::EType type) { auto append_range_item = [append_item](int i, float value) { std::string str_value = get_time_dhms(value); if (str_value == "0s") @@ -3233,9 +3263,16 @@ void GCodeViewer::render_legend(float& legend_height) append_range_item(0, range.min); } else { - const float step_size = range.step_size(); + float step_size = range.step_size(type); for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) { - append_range_item(i, range.min + static_cast(i) * step_size); + float value = 0.0f; + switch (type) + { + default: + case Extrusions::Range::EType::Linear: { value = range.min + static_cast(i) * step_size; break; } + case Extrusions::Range::EType::Logarithmic: { value = ::exp(::log(range.min) + static_cast(i) * step_size); break; } + } + append_range_item(i, value); } } }; @@ -3416,20 +3453,21 @@ void GCodeViewer::render_legend(float& legend_height) append_headers({ _u8L("Feature type"), _u8L("Time"), _u8L("Percentage"), _u8L("Used filament") }, offsets); break; } - case EViewType::Height: { imgui.title(_u8L("Height (mm)")); break; } - case EViewType::Width: { imgui.title(_u8L("Width (mm)")); break; } - case EViewType::Feedrate: { imgui.title(_u8L("Speed (mm/s)")); break; } - case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; } - case EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; } - case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } + case EViewType::Height: { imgui.title(_u8L("Height (mm)")); break; } + case EViewType::Width: { imgui.title(_u8L("Width (mm)")); break; } + case EViewType::Feedrate: { imgui.title(_u8L("Speed (mm/s)")); break; } + case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; } + case EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; } + case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } #if ENABLE_PREVIEW_LAYER_TIME - case EViewType::LayerTime: { imgui.title(_u8L("Layer time")); break; } + case EViewType::LayerTimeLinear: { imgui.title(_u8L("Layer time (linear)")); break; } + case EViewType::LayerTimeLogarithmic: { imgui.title(_u8L("Layer time (logarithmic)")); break; } #endif // ENABLE_PREVIEW_LAYER_TIME - case EViewType::Tool: { + case EViewType::Tool: { append_headers({ _u8L("Tool"), _u8L("Used filament") }, offsets); break; } - case EViewType::ColorPrint: { imgui.title(_u8L("Color Print")); break; } + case EViewType::ColorPrint: { imgui.title(_u8L("Color Print")); break; } default: { break; } } @@ -3456,16 +3494,17 @@ void GCodeViewer::render_legend(float& legend_height) } break; } - case EViewType::Height: { append_range(m_extrusions.ranges.height, 3); break; } - case EViewType::Width: { append_range(m_extrusions.ranges.width, 3); break; } - case EViewType::Feedrate: { append_range(m_extrusions.ranges.feedrate, 1); break; } - case EViewType::FanSpeed: { append_range(m_extrusions.ranges.fan_speed, 0); break; } - case EViewType::Temperature: { append_range(m_extrusions.ranges.temperature, 0); break; } - case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; } + case EViewType::Height: { append_range(m_extrusions.ranges.height, 3); break; } + case EViewType::Width: { append_range(m_extrusions.ranges.width, 3); break; } + case EViewType::Feedrate: { append_range(m_extrusions.ranges.feedrate, 1); break; } + case EViewType::FanSpeed: { append_range(m_extrusions.ranges.fan_speed, 0); break; } + case EViewType::Temperature: { append_range(m_extrusions.ranges.temperature, 0); break; } + case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; } #if ENABLE_PREVIEW_LAYER_TIME - case EViewType::LayerTime: { append_time_range(m_extrusions.ranges.layer_time[static_cast(m_time_estimate_mode)]); break; } + case EViewType::LayerTimeLinear: { append_time_range(m_extrusions.ranges.layer_time[static_cast(m_time_estimate_mode)], Extrusions::Range::EType::Linear); break; } + case EViewType::LayerTimeLogarithmic: { append_time_range(m_extrusions.ranges.layer_time[static_cast(m_time_estimate_mode)], Extrusions::Range::EType::Logarithmic); break; } #endif // ENABLE_PREVIEW_LAYER_TIME - case EViewType::Tool: { + case EViewType::Tool: { // shows only extruders actually used size_t i = 0; for (unsigned char extruder_id : m_extruder_ids) { @@ -3475,7 +3514,7 @@ void GCodeViewer::render_legend(float& legend_height) } break; } - case EViewType::ColorPrint: { + case EViewType::ColorPrint: { #if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER const std::vector& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z; #else @@ -3924,7 +3963,7 @@ void GCodeViewer::render_legend(float& legend_height) if (imgui.button(label)) { m_time_estimate_mode = mode; #if ENABLE_PREVIEW_LAYER_TIME - if (m_view_type == EViewType::LayerTime) + if (m_view_type == EViewType::LayerTimeLinear || m_view_type == EViewType::LayerTimeLogarithmic) refresh_render_paths(); #endif // ENABLE_PREVIEW_LAYER_TIME wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index fe88cc5391..28f009c7a6 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -429,6 +429,14 @@ class GCodeViewer { struct Range { +#if ENABLE_PREVIEW_LAYER_TIME + enum class EType : unsigned char + { + Linear, + Logarithmic + }; +#endif // ENABLE_PREVIEW_LAYER_TIME + float min; float max; unsigned int count; @@ -443,8 +451,13 @@ class GCodeViewer } void reset() { min = FLT_MAX; max = -FLT_MAX; count = 0; } +#if ENABLE_PREVIEW_LAYER_TIME + float step_size(EType type = EType::Linear) const; + Color get_color_at(float value, EType type = EType::Linear) const; +#else float step_size() const { return (max - min) / (static_cast(Range_Colors.size()) - 1.0f); } Color get_color_at(float value) const; +#endif // ENABLE_PREVIEW_LAYER_TIME }; struct Ranges @@ -756,7 +769,8 @@ public: Temperature, VolumetricRate, #if ENABLE_PREVIEW_LAYER_TIME - LayerTime, + LayerTimeLinear, + LayerTimeLogarithmic, #endif // ENABLE_PREVIEW_LAYER_TIME Tool, ColorPrint, diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 231fa92067..f6a96cf0d6 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -226,7 +226,8 @@ bool Preview::init(wxWindow* parent, Model* model) m_choice_view_type->Append(_L("Temperature")); m_choice_view_type->Append(_L("Volumetric flow rate")); #if ENABLE_PREVIEW_LAYER_TIME - m_choice_view_type->Append(_L("Layer time")); + m_choice_view_type->Append(_L("Layer time (linear)")); + m_choice_view_type->Append(_L("Layer time (logarithmic)")); #endif // ENABLE_PREVIEW_LAYER_TIME m_choice_view_type->Append(_L("Tool")); m_choice_view_type->Append(_L("Color Print")); From 7f89a42be6d3c40b7fb5824e8abfe5c13992d6f2 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 14 Sep 2021 08:15:47 +0200 Subject: [PATCH 04/27] Tech ENABLE_PREVIEW_LAYOUT - 1st installment: move view type combo from bottom toolbar to legend --- src/libslic3r/Technologies.hpp | 2 ++ src/slic3r/GUI/GCodeViewer.cpp | 32 ++++++++++++++++++++++++++++++++ src/slic3r/GUI/GUI_Preview.cpp | 26 ++++++++++++++++++++++++++ src/slic3r/GUI/GUI_Preview.hpp | 6 ++++++ src/slic3r/GUI/ImGuiWrapper.cpp | 10 ++++++++-- 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index ac92ecd108..dfd03fbedf 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -66,6 +66,8 @@ #define ENABLE_SEAMS_USING_BATCHED_MODELS (1 && ENABLE_SEAMS_USING_MODELS && ENABLE_2_4_0_ALPHA2) // Enable fixing the z position of color change, pause print and custom gcode markers in preview #define ENABLE_FIX_PREVIEW_OPTIONS_Z (1 && ENABLE_SEAMS_USING_MODELS && ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER && ENABLE_2_4_0_ALPHA2) +// Enable changes in preview layout +#define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_4_0_ALPHA2) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 9b7d8ec47c..d60935978d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3344,6 +3344,31 @@ void GCodeViewer::render_legend(float& legend_height) offsets = calculate_offsets(labels, times, { "Extruder NNN", longest_used_filament_string }, icon_size); } +#if ENABLE_PREVIEW_LAYOUT + // selection section + bool selection_changed = false; + int view_type = static_cast(get_view_type()); + int old_view_type = view_type; + if (imgui.combo("", { _u8L("Feature type"), + _u8L("Height (mm)"), + _u8L("Width (mm)"), + _u8L("Speed (mm/s)"), + _u8L("Fan speed (%)"), + _u8L("Temperature (°C)"), + _u8L("Volumetric flow rate (mm³/s)"), + _u8L("Tool"), + _u8L("Color Print") }, view_type)) { + set_view_type(static_cast(view_type)); + wxGetApp().plater()->refresh_print(); + selection_changed = old_view_type != view_type; + } + + // extrusion paths section -> title + if (m_view_type == EViewType::FeatureType) + append_headers({ _u8L(""), _u8L("Time"), _u8L("Percentage"), _u8L("Used filament") }, offsets); + else + ImGui::Separator(); +#else // extrusion paths section -> title switch (m_view_type) { @@ -3366,7 +3391,11 @@ void GCodeViewer::render_legend(float& legend_height) case EViewType::ColorPrint: { imgui.title(_u8L("Color Print")); break; } default: { break; } } +#endif // ENABLE_PREVIEW_LAYOUT +#if ENABLE_PREVIEW_LAYOUT + if (!selection_changed) { +#endif // ENABLE_PREVIEW_LAYOUT // extrusion paths section -> items switch (m_view_type) { @@ -3481,6 +3510,9 @@ void GCodeViewer::render_legend(float& legend_height) } default: { break; } } +#if ENABLE_PREVIEW_LAYOUT + } +#endif // ENABLE_PREVIEW_LAYOUT // partial estimated printing time section if (m_view_type == EViewType::ColorPrint) { diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index f8a10bb8e9..3375702e38 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -207,6 +207,7 @@ bool Preview::init(wxWindow* parent, Model* model) m_layers_slider_sizer = create_layers_slider_sizer(); wxGetApp().UpdateDarkUI(m_bottom_toolbar_panel = new wxPanel(this)); +#if !ENABLE_PREVIEW_LAYOUT m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View")); #ifdef _WIN32 wxGetApp().UpdateDarkUI(m_choice_view_type = new BitmapComboBox(m_bottom_toolbar_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY)); @@ -223,6 +224,7 @@ bool Preview::init(wxWindow* parent, Model* model) m_choice_view_type->Append(_L("Tool")); m_choice_view_type->Append(_L("Color Print")); m_choice_view_type->SetSelection(0); +#endif // !ENABLE_PREVIEW_LAYOUT m_label_show = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("Show")); @@ -231,6 +233,7 @@ bool Preview::init(wxWindow* parent, Model* model) #else long combo_style = wxCB_READONLY; #endif +#if !ENABLE_PREVIEW_LAYOUT m_combochecklist_features = new wxComboCtrl(); m_combochecklist_features->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, combo_style); std::string feature_items = GUI::into_u8( @@ -251,6 +254,7 @@ bool Preview::init(wxWindow* parent, Model* model) _L("Custom") + "|1" ); Slic3r::GUI::create_combochecklist(m_combochecklist_features, GUI::into_u8(_L("Feature types")), feature_items); +#endif // !ENABLE_PREVIEW_LAYOUT m_combochecklist_options = new wxComboCtrl(); m_combochecklist_options->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, combo_style); @@ -280,16 +284,20 @@ bool Preview::init(wxWindow* parent, Model* model) m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); wxBoxSizer* bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); +#if !ENABLE_PREVIEW_LAYOUT bottom_toolbar_sizer->AddSpacer(5); bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 0); +#endif // !ENABLE_PREVIEW_LAYOUT bottom_toolbar_sizer->AddSpacer(5); bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 0); +#if !ENABLE_PREVIEW_LAYOUT // change the following number if editing the layout of the bottom toolbar sizer. It is used into update_bottom_toolbar() m_combochecklist_features_pos = 6; bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); bottom_toolbar_sizer->Hide(m_combochecklist_features); +#endif // !ENABLE_PREVIEW_LAYOUT bottom_toolbar_sizer->AddSpacer(5); bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 0); m_bottom_toolbar_panel->SetSizer(bottom_toolbar_sizer); @@ -395,10 +403,12 @@ void Preview::refresh_print() void Preview::msw_rescale() { +#if !ENABLE_PREVIEW_LAYOUT #ifdef _WIN32 m_choice_view_type->Rescale(); m_choice_view_type->SetMinSize(m_choice_view_type->GetSize()); #endif +#endif // !ENABLE_PREVIEW_LAYOUT // rescale slider if (m_layers_slider != nullptr) m_layers_slider->msw_rescale(); if (m_moves_slider != nullptr) m_moves_slider->msw_rescale(); @@ -416,9 +426,11 @@ void Preview::sys_color_changed() wxWindowUpdateLocker noUpdates(this); wxGetApp().UpdateAllStaticTextDarkUI(m_bottom_toolbar_panel); +#if !ENABLE_PREVIEW_LAYOUT wxGetApp().UpdateDarkUI(m_choice_view_type); wxGetApp().UpdateDarkUI(m_combochecklist_features); wxGetApp().UpdateDarkUI(static_cast(m_combochecklist_features->GetPopupControl())); +#endif // !ENABLE_PREVIEW_LAYOUT wxGetApp().UpdateDarkUI(m_combochecklist_options); wxGetApp().UpdateDarkUI(static_cast(m_combochecklist_options->GetPopupControl())); #endif @@ -445,8 +457,10 @@ void Preview::edit_layers_slider(wxKeyEvent& evt) void Preview::bind_event_handlers() { this->Bind(wxEVT_SIZE, &Preview::on_size, this); +#if !ENABLE_PREVIEW_LAYOUT m_choice_view_type->Bind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this); m_combochecklist_features->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); +#endif // !ENABLE_PREVIEW_LAYOUT m_combochecklist_options->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); } @@ -454,8 +468,10 @@ void Preview::bind_event_handlers() void Preview::unbind_event_handlers() { this->Unbind(wxEVT_SIZE, &Preview::on_size, this); +#if !ENABLE_PREVIEW_LAYOUT m_choice_view_type->Unbind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this); m_combochecklist_features->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); +#endif // !ENABLE_PREVIEW_LAYOUT m_combochecklist_options->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); m_moves_slider->Unbind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); } @@ -477,6 +493,7 @@ void Preview::on_size(wxSizeEvent& evt) Refresh(); } +#if !ENABLE_PREVIEW_LAYOUT void Preview::on_choice_view_type(wxCommandEvent& evt) { int selection = m_choice_view_type->GetCurrentSelection(); @@ -493,6 +510,7 @@ void Preview::on_combochecklist_features(wxCommandEvent& evt) m_canvas->set_toolpath_role_visibility_flags(flags); refresh_print(); } +#endif // !ENABLE_PREVIEW_LAYOUT void Preview::on_combochecklist_options(wxCommandEvent& evt) { @@ -508,9 +526,12 @@ void Preview::on_combochecklist_options(wxCommandEvent& evt) void Preview::update_bottom_toolbar() { +#if !ENABLE_PREVIEW_LAYOUT combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags()); +#endif // !ENABLE_PREVIEW_LAYOUT combochecklist_set_flags(m_combochecklist_options, m_canvas->get_gcode_options_visibility_flags()); +#if !ENABLE_PREVIEW_LAYOUT // updates visibility of features combobox if (m_bottom_toolbar_panel->IsShown()) { wxSizer* sizer = m_bottom_toolbar_panel->GetSizer(); @@ -533,6 +554,7 @@ void Preview::update_bottom_toolbar() } } } +#endif // !ENABLE_PREVIEW_LAYOUT } wxBoxSizer* Preview::create_layers_slider_sizer() @@ -975,6 +997,9 @@ void Preview::load_print_as_fff(bool keep_z_range) _L("Color Print") : (number_extruders > 1) ? _L("Tool") : _L("Feature type"); +#if ENABLE_PREVIEW_LAYOUT + GCodeViewer::EViewType view_type = m_canvas->get_gcode_view_type(); +#else int type = m_choice_view_type->FindString(choice); if (m_choice_view_type->GetSelection() != type) { if (0 <= type && type < static_cast(GCodeViewer::EViewType::Count)) { @@ -986,6 +1011,7 @@ void Preview::load_print_as_fff(bool keep_z_range) } } } +#endif // ENABLE_PREVIEW_LAYOUT } #endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 97ced0a1e0..91d126e344 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -80,15 +80,19 @@ class Preview : public wxPanel wxBoxSizer* m_left_sizer { nullptr }; wxBoxSizer* m_layers_slider_sizer { nullptr }; wxPanel* m_bottom_toolbar_panel { nullptr }; +#if !ENABLE_PREVIEW_LAYOUT wxStaticText* m_label_view_type { nullptr }; #ifdef _WIN32 BitmapComboBox* m_choice_view_type { nullptr }; #else wxComboBox* m_choice_view_type { nullptr }; #endif +#endif // !ENABLE_PREVIEW_LAYOUT wxStaticText* m_label_show { nullptr }; +#if !ENABLE_PREVIEW_LAYOUT wxComboCtrl* m_combochecklist_features { nullptr }; size_t m_combochecklist_features_pos { 0 }; +#endif // !ENABLE_PREVIEW_LAYOUT wxComboCtrl* m_combochecklist_options { nullptr }; DynamicPrintConfig* m_config; @@ -167,8 +171,10 @@ private: void unbind_event_handlers(); void on_size(wxSizeEvent& evt); +#if !ENABLE_PREVIEW_LAYOUT void on_choice_view_type(wxCommandEvent& evt); void on_combochecklist_features(wxCommandEvent& evt); +#endif // !ENABLE_PREVIEW_LAYOUT void on_combochecklist_options(wxCommandEvent& evt); // Create/Update/Reset double slider on 3dPreview diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index fa9845c5d7..7bdfb15c71 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -444,8 +444,14 @@ bool ImGuiWrapper::slider_float(const wxString& label, float* v, float v_min, fl bool ImGuiWrapper::combo(const wxString& label, const std::vector& options, int& selection) { // this is to force the label to the left of the widget: - text(label); - ImGui::SameLine(); +#if ENABLE_PREVIEW_LAYOUT + if (!label.empty()) { +#endif // ENABLE_PREVIEW_LAYOUT + text(label); + ImGui::SameLine(); +#if ENABLE_PREVIEW_LAYOUT + } +#endif // ENABLE_PREVIEW_LAYOUT int selection_out = selection; bool res = false; From cddfc8b690ad87d40320d9ea557ed8244543ffd8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 14 Sep 2021 10:32:17 +0200 Subject: [PATCH 05/27] Tech ENABLE_PREVIEW_LAYOUT - A few fixes in the new legend layout --- src/slic3r/GUI/GCodeViewer.cpp | 33 +++++++++++++++++++-------------- src/slic3r/GUI/GUI_Preview.cpp | 16 ++++++++++++---- src/slic3r/GUI/GUI_Preview.hpp | 4 ++++ src/slic3r/GUI/Plater.cpp | 6 ++++++ src/slic3r/GUI/Plater.hpp | 4 ++++ 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index d60935978d..ac47494598 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3346,21 +3346,26 @@ void GCodeViewer::render_legend(float& legend_height) #if ENABLE_PREVIEW_LAYOUT // selection section - bool selection_changed = false; - int view_type = static_cast(get_view_type()); - int old_view_type = view_type; - if (imgui.combo("", { _u8L("Feature type"), - _u8L("Height (mm)"), - _u8L("Width (mm)"), - _u8L("Speed (mm/s)"), - _u8L("Fan speed (%)"), - _u8L("Temperature (°C)"), - _u8L("Volumetric flow rate (mm³/s)"), - _u8L("Tool"), - _u8L("Color Print") }, view_type)) { + bool view_type_changed = false; + int old_view_type = static_cast(get_view_type()); + int view_type = old_view_type; + ImGuiStyle& style = ImGui::GetStyle(); + ImGui::PushItemWidth(ImGui::GetWindowWidth() - style.ItemSpacing.x - 2.0f * style.FramePadding.x); + imgui.combo("", { _u8L("Feature type"), + _u8L("Height (mm)"), + _u8L("Width (mm)"), + _u8L("Speed (mm/s)"), + _u8L("Fan speed (%)"), + _u8L("Temperature (°C)"), + _u8L("Volumetric flow rate (mm³/s)"), + _u8L("Tool"), + _u8L("Color Print") }, view_type); + + if (old_view_type != view_type) { set_view_type(static_cast(view_type)); + wxGetApp().plater()->set_keep_current_preview_type(true); wxGetApp().plater()->refresh_print(); - selection_changed = old_view_type != view_type; + view_type_changed = true; } // extrusion paths section -> title @@ -3394,7 +3399,7 @@ void GCodeViewer::render_legend(float& legend_height) #endif // ENABLE_PREVIEW_LAYOUT #if ENABLE_PREVIEW_LAYOUT - if (!selection_changed) { + if (!view_type_changed) { #endif // ENABLE_PREVIEW_LAYOUT // extrusion paths section -> items switch (m_view_type) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 3375702e38..65bcf212d9 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -993,13 +993,21 @@ void Preview::load_print_as_fff(bool keep_z_range) std::vector gcodes = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_canvas->get_custom_gcode_per_print_z(); +#if ENABLE_PREVIEW_LAYOUT + const GCodeViewer::EViewType choice = !gcodes.empty() ? + GCodeViewer::EViewType::ColorPrint : + (number_extruders > 1) ? GCodeViewer::EViewType::Tool : GCodeViewer::EViewType::FeatureType; + if (choice != gcode_view_type) { + m_canvas->set_gcode_view_preview_type(choice); + if (wxGetApp().is_gcode_viewer()) { + m_keep_current_preview_type = true; + refresh_print(); + } + } +#else const wxString choice = !gcodes.empty() ? _L("Color Print") : (number_extruders > 1) ? _L("Tool") : _L("Feature type"); - -#if ENABLE_PREVIEW_LAYOUT - GCodeViewer::EViewType view_type = m_canvas->get_gcode_view_type(); -#else int type = m_choice_view_type->FindString(choice); if (m_choice_view_type->GetSelection() != type) { if (0 <= type && type < static_cast(GCodeViewer::EViewType::Count)) { diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 91d126e344..bf3db0915e 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -164,6 +164,10 @@ public: void move_moves_slider(wxKeyEvent& evt); void hide_layers_slider(); +#if ENABLE_PREVIEW_LAYOUT + void set_keep_current_preview_type(bool value) { m_keep_current_preview_type = value; } +#endif // ENABLE_PREVIEW_LAYOUT + private: bool init(wxWindow* parent, Model* model); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7d344c389b..6506cb2c1b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6606,6 +6606,12 @@ bool Plater::is_render_statistic_dialog_visible() const return p->show_render_statistic_dialog; } +#if ENABLE_PREVIEW_LAYOUT +void Plater::set_keep_current_preview_type(bool value) +{ + p->preview->set_keep_current_preview_type(value); +} +#endif // ENABLE_PREVIEW_LAYOUT Plater::TakeSnapshot::TakeSnapshot(Plater *plater, const std::string &snapshot_name) : TakeSnapshot(plater, from_u8(snapshot_name)) {} diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 4a98797e5d..dffb2451f3 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -403,6 +403,10 @@ public: void toggle_render_statistic_dialog(); bool is_render_statistic_dialog_visible() const; +#if ENABLE_PREVIEW_LAYOUT + void set_keep_current_preview_type(bool value); +#endif // ENABLE_PREVIEW_LAYOUT + // Wrapper around wxWindow::PopupMenu to suppress error messages popping out while tracking the popup menu. bool PopupMenu(wxMenu *menu, const wxPoint& pos = wxDefaultPosition); bool PopupMenu(wxMenu *menu, int x, int y) { return this->PopupMenu(menu, wxPoint(x, y)); } From 3f1c845089155333d9fb7feb544c769aafabdb81 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Sep 2021 12:05:35 +0200 Subject: [PATCH 06/27] Tech ENABLE_PREVIEW_LAYOUT - Darker background for the new combo into legend --- src/slic3r/GUI/GCodeViewer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index ac47494598..742a114597 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3351,6 +3351,8 @@ void GCodeViewer::render_legend(float& legend_height) int view_type = old_view_type; ImGuiStyle& style = ImGui::GetStyle(); ImGui::PushItemWidth(ImGui::GetWindowWidth() - style.ItemSpacing.x - 2.0f * style.FramePadding.x); + ImGui::PushStyleColor(ImGuiCol_FrameBg, { 0.1f, 0.1f, 0.1f, 0.8f }); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, { 0.2f, 0.2f, 0.2f, 0.8f }); imgui.combo("", { _u8L("Feature type"), _u8L("Height (mm)"), _u8L("Width (mm)"), @@ -3360,6 +3362,7 @@ void GCodeViewer::render_legend(float& legend_height) _u8L("Volumetric flow rate (mm³/s)"), _u8L("Tool"), _u8L("Color Print") }, view_type); + ImGui::PopStyleColor(2); if (old_view_type != view_type) { set_view_type(static_cast(view_type)); From e12cf58c913017ceab660b6f4ef9ba8c6f6dc19d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 24 Sep 2021 09:22:50 +0200 Subject: [PATCH 07/27] Tech ENABLE_PREVIEW_LAYOUT - Replace options combo in bottom toolbar with toolbar in legend --- src/slic3r/GUI/GCodeViewer.cpp | 118 +++++++++++++++++++++++++++++++- src/slic3r/GUI/GLCanvas3D.cpp | 2 + src/slic3r/GUI/GUI_Preview.cpp | 29 ++++---- src/slic3r/GUI/GUI_Preview.hpp | 14 ++-- src/slic3r/GUI/ImGuiWrapper.cpp | 36 ++++++++++ src/slic3r/GUI/ImGuiWrapper.hpp | 8 ++- src/slic3r/GUI/Plater.cpp | 6 ++ src/slic3r/GUI/Plater.hpp | 2 + 8 files changed, 191 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 1ae39ef68f..b901ca01ef 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -959,7 +959,9 @@ unsigned int GCodeViewer::get_options_visibility_flags() const flags = set_flag(flags, static_cast(Preview::OptionType::CustomGCodes), is_toolpath_move_type_visible(EMoveType::Custom_GCode)); flags = set_flag(flags, static_cast(Preview::OptionType::Shells), m_shells.visible); flags = set_flag(flags, static_cast(Preview::OptionType::ToolMarker), m_sequential_view.marker.is_visible()); +#if !ENABLE_PREVIEW_LAYOUT flags = set_flag(flags, static_cast(Preview::OptionType::Legend), is_legend_enabled()); +#endif // !ENABLE_PREVIEW_LAYOUT return flags; } @@ -980,7 +982,9 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) set_toolpath_move_type_visible(EMoveType::Custom_GCode, is_flag_set(static_cast(Preview::OptionType::CustomGCodes))); m_shells.visible = is_flag_set(static_cast(Preview::OptionType::Shells)); m_sequential_view.marker.set_visible(is_flag_set(static_cast(Preview::OptionType::ToolMarker))); +#if !ENABLE_PREVIEW_LAYOUT enable_legend(is_flag_set(static_cast(Preview::OptionType::Legend))); +#endif // !ENABLE_PREVIEW_LAYOUT } void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) @@ -3575,7 +3579,9 @@ void GCodeViewer::render_legend(float& legend_height) refresh_render_paths(false, false); wxGetApp().plater()->update_preview_moves_slider(); wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); +#if !ENABLE_PREVIEW_LAYOUT wxGetApp().plater()->update_preview_bottom_toolbar(); +#endif // !ENABLE_PREVIEW_LAYOUT } ); } @@ -3846,6 +3852,7 @@ void GCodeViewer::render_legend(float& legend_height) } } +#if !ENABLE_PREVIEW_LAYOUT // travel paths section if (m_buffers[buffer_id(EMoveType::Travel)].visible) { switch (m_view_type) @@ -3930,6 +3937,7 @@ void GCodeViewer::render_legend(float& legend_height) add_option(EMoveType::Pause_Print, EOptionsColors::PausePrints, _u8L("Print pauses")); add_option(EMoveType::Custom_GCode, EOptionsColors::CustomGCodes, _u8L("Custom G-codes")); } +#endif // !ENABLE_PREVIEW_LAYOUT // settings section bool has_settings = false; @@ -4050,17 +4058,123 @@ void GCodeViewer::render_legend(float& legend_height) switch (m_time_estimate_mode) { case PrintEstimatedStatistics::ETimeMode::Normal: { - show_mode_button(_L("Show stealth mode"), PrintEstimatedStatistics::ETimeMode::Stealth); + show_mode_button(_u8L("Show stealth mode"), PrintEstimatedStatistics::ETimeMode::Stealth); break; } case PrintEstimatedStatistics::ETimeMode::Stealth: { - show_mode_button(_L("Show normal mode"), PrintEstimatedStatistics::ETimeMode::Normal); + show_mode_button(_u8L("Show normal mode"), PrintEstimatedStatistics::ETimeMode::Normal); break; } default : { assert(false); break; } } } +#if ENABLE_PREVIEW_LAYOUT + // toolbar section + auto toggle_button = [this, &imgui, icon_size](Preview::OptionType type, const std::string& name, + std::function draw_callback) { + auto is_flag_set = [](unsigned int flags, unsigned int flag) { + return (flags & (1 << flag)) != 0; + }; + + auto set_flag = [](unsigned int flags, unsigned int flag, bool active) { + return active ? (flags | (1 << flag)) : (flags & ~(1 << flag)); + }; + + unsigned int flags = get_options_visibility_flags(); + unsigned int flag = static_cast(type); + bool active = is_flag_set(flags, flag); + + if (imgui.draw_radio_button(name, 1.5f * icon_size, active, draw_callback)) { + unsigned int new_flags = set_flag(flags, flag, !active); + set_options_visibility_from_flags(new_flags); + + wxGetApp().plater()->get_current_canvas3D()->refresh_gcode_preview_render_paths(); + wxGetApp().plater()->update_preview_moves_slider(); + } + + if (ImGui::IsItemHovered()) { + ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND); + ImGui::BeginTooltip(); + imgui.text(name); + ImGui::EndTooltip(); + ImGui::PopStyleColor(); + } + }; + + auto circle_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) { + const float margin = 3.0f; + const ImVec2 center(0.5f * (pos.x + pos.x + size), 0.5f * (pos.y + pos.y + size)); + window.DrawList->AddCircleFilled(center, 0.5f * (size - 2.0f * margin), ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + }; + auto line_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) { + const float margin = 3.0f; + window.DrawList->AddLine({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin, pos.y + margin }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); + }; + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + toggle_button(Preview::OptionType::Travel, _u8L("Travel"), [line_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + line_icon(window, pos, size, Travel_Colors[0]); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::Wipe, _u8L("Wipe"), [line_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + line_icon(window, pos, size, Wipe_Color); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::Retractions, _u8L("Retractions"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::Retractions)]); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::Unretractions, _u8L("Deretractions"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::Unretractions)]); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::Seams, _u8L("Seams"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::Seams)]); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::ToolChanges, _u8L("Tool changes"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::ToolChanges)]); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::ColorChanges, _u8L("Color changes"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::ColorChanges)]); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::PausePrints, _u8L("Print pauses"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::PausePrints)]); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::CustomGCodes, _u8L("Custom G-codes"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::Shells, _u8L("Shells"), [](ImGuiWindow& window, const ImVec2& pos, float size) { + const ImU32 color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 1.0f }); + const float margin = 3.0f; + const float proj = 0.25f * size; + window.DrawList->AddRect({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin - proj, pos.y + margin + proj }, color); + window.DrawList->AddLine({ pos.x + margin, pos.y + margin + proj }, { pos.x + margin + proj, pos.y + margin }, color); + window.DrawList->AddLine({ pos.x + size - margin - proj, pos.y + margin + proj }, { pos.x + size - margin, pos.y + margin }, color); + window.DrawList->AddLine({ pos.x + size - margin - proj, pos.y + size - margin }, { pos.x + size - margin, pos.y + size - margin - proj }, color); + window.DrawList->AddLine({ pos.x + margin + proj, pos.y + margin }, { pos.x + size - margin, pos.y + margin }, color); + window.DrawList->AddLine({ pos.x + size - margin, pos.y + margin }, { pos.x + size - margin, pos.y + size - margin - proj }, color); + }); + ImGui::SameLine(); + toggle_button(Preview::OptionType::ToolMarker, _u8L("Tool marker"), [](ImGuiWindow& window, const ImVec2& pos, float size) { + const ImU32 color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.8f }); + const float margin = 3.0f; + const ImVec2 p1(0.5f * (pos.x + pos.x + size), pos.y + size - margin); + const ImVec2 p2 = ImVec2(p1.x + 0.25f * size, p1.y - 0.25f * size); + const ImVec2 p3 = ImVec2(p1.x - 0.25f * size, p1.y - 0.25f * size); + window.DrawList->AddTriangleFilled(p1, p2, p3, color); + const float mid_x = 0.5f * (pos.x + pos.x + size); + window.DrawList->AddRectFilled({ mid_x - 0.09375f * size, p1.y - 0.25f * size }, { mid_x + 0.09375f * size, pos.y + margin }, color); + }); +#endif // ENABLE_PREVIEW_LAYOUT + legend_height = ImGui::GetCurrentWindow()->Size.y; imgui.end(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e2aa6fb7b8..45d1900808 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2410,7 +2410,9 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) if (!m_main_toolbar.is_enabled()) { m_gcode_viewer.enable_legend(!m_gcode_viewer.is_legend_enabled()); m_dirty = true; +#if !ENABLE_PREVIEW_LAYOUT wxGetApp().plater()->update_preview_bottom_toolbar(); +#endif // !ENABLE_PREVIEW_LAYOUT } break; } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 99dea09a88..9f6159cb40 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -224,7 +224,6 @@ bool Preview::init(wxWindow* parent, Model* model) m_choice_view_type->Append(_L("Tool")); m_choice_view_type->Append(_L("Color Print")); m_choice_view_type->SetSelection(0); -#endif // !ENABLE_PREVIEW_LAYOUT m_label_show = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("Show")); @@ -233,7 +232,7 @@ bool Preview::init(wxWindow* parent, Model* model) #else long combo_style = wxCB_READONLY; #endif -#if !ENABLE_PREVIEW_LAYOUT + m_combochecklist_features = new wxComboCtrl(); m_combochecklist_features->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, combo_style); std::string feature_items = GUI::into_u8( @@ -254,7 +253,6 @@ bool Preview::init(wxWindow* parent, Model* model) _L("Custom") + "|1" ); Slic3r::GUI::create_combochecklist(m_combochecklist_features, GUI::into_u8(_L("Feature types")), feature_items); -#endif // !ENABLE_PREVIEW_LAYOUT m_combochecklist_options = new wxComboCtrl(); m_combochecklist_options->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, combo_style); @@ -273,6 +271,7 @@ bool Preview::init(wxWindow* parent, Model* model) get_option_type_string(OptionType::Legend) + "|1" ); Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items); +#endif // !ENABLE_PREVIEW_LAYOUT m_left_sizer = new wxBoxSizer(wxVERTICAL); m_left_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); @@ -288,17 +287,15 @@ bool Preview::init(wxWindow* parent, Model* model) bottom_toolbar_sizer->AddSpacer(5); bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 0); -#endif // !ENABLE_PREVIEW_LAYOUT bottom_toolbar_sizer->AddSpacer(5); bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 0); -#if !ENABLE_PREVIEW_LAYOUT // change the following number if editing the layout of the bottom toolbar sizer. It is used into update_bottom_toolbar() m_combochecklist_features_pos = 6; bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); bottom_toolbar_sizer->Hide(m_combochecklist_features); -#endif // !ENABLE_PREVIEW_LAYOUT bottom_toolbar_sizer->AddSpacer(5); +#endif // !ENABLE_PREVIEW_LAYOUT bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 0); m_bottom_toolbar_panel->SetSizer(bottom_toolbar_sizer); @@ -360,7 +357,9 @@ void Preview::load_print(bool keep_z_range) else if (tech == ptSLA) load_print_as_sla(); +#if !ENABLE_PREVIEW_LAYOUT update_bottom_toolbar(); +#endif // !ENABLE_PREVIEW_LAYOUT Layout(); } @@ -430,9 +429,9 @@ void Preview::sys_color_changed() wxGetApp().UpdateDarkUI(m_choice_view_type); wxGetApp().UpdateDarkUI(m_combochecklist_features); wxGetApp().UpdateDarkUI(static_cast(m_combochecklist_features->GetPopupControl())); -#endif // !ENABLE_PREVIEW_LAYOUT wxGetApp().UpdateDarkUI(m_combochecklist_options); wxGetApp().UpdateDarkUI(static_cast(m_combochecklist_options->GetPopupControl())); +#endif // !ENABLE_PREVIEW_LAYOUT #endif if (m_layers_slider != nullptr) @@ -456,23 +455,23 @@ void Preview::edit_layers_slider(wxKeyEvent& evt) void Preview::bind_event_handlers() { - this->Bind(wxEVT_SIZE, &Preview::on_size, this); + Bind(wxEVT_SIZE, &Preview::on_size, this); #if !ENABLE_PREVIEW_LAYOUT m_choice_view_type->Bind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this); m_combochecklist_features->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); -#endif // !ENABLE_PREVIEW_LAYOUT m_combochecklist_options->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); +#endif // !ENABLE_PREVIEW_LAYOUT m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); } void Preview::unbind_event_handlers() { - this->Unbind(wxEVT_SIZE, &Preview::on_size, this); + Unbind(wxEVT_SIZE, &Preview::on_size, this); #if !ENABLE_PREVIEW_LAYOUT m_choice_view_type->Unbind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this); m_combochecklist_features->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); -#endif // !ENABLE_PREVIEW_LAYOUT m_combochecklist_options->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); +#endif // !ENABLE_PREVIEW_LAYOUT m_moves_slider->Unbind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); } @@ -510,7 +509,6 @@ void Preview::on_combochecklist_features(wxCommandEvent& evt) m_canvas->set_toolpath_role_visibility_flags(flags); refresh_print(); } -#endif // !ENABLE_PREVIEW_LAYOUT void Preview::on_combochecklist_options(wxCommandEvent& evt) { @@ -526,12 +524,9 @@ void Preview::on_combochecklist_options(wxCommandEvent& evt) void Preview::update_bottom_toolbar() { -#if !ENABLE_PREVIEW_LAYOUT combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags()); -#endif // !ENABLE_PREVIEW_LAYOUT combochecklist_set_flags(m_combochecklist_options, m_canvas->get_gcode_options_visibility_flags()); -#if !ENABLE_PREVIEW_LAYOUT // updates visibility of features combobox if (m_bottom_toolbar_panel->IsShown()) { wxSizer* sizer = m_bottom_toolbar_panel->GetSizer(); @@ -554,8 +549,8 @@ void Preview::update_bottom_toolbar() } } } -#endif // !ENABLE_PREVIEW_LAYOUT } +#endif // !ENABLE_PREVIEW_LAYOUT wxBoxSizer* Preview::create_layers_slider_sizer() { @@ -1077,6 +1072,7 @@ void Preview::on_moves_slider_scroll_changed(wxCommandEvent& event) m_canvas->render(); } +#if !ENABLE_PREVIEW_LAYOUT wxString Preview::get_option_type_string(OptionType type) const { switch (type) @@ -1096,6 +1092,7 @@ wxString Preview::get_option_type_string(OptionType type) const default: { return ""; } } } +#endif // !ENABLE_PREVIEW_LAYOUT } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index bf3db0915e..fe63b44a72 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -87,13 +87,11 @@ class Preview : public wxPanel #else wxComboBox* m_choice_view_type { nullptr }; #endif -#endif // !ENABLE_PREVIEW_LAYOUT - wxStaticText* m_label_show { nullptr }; -#if !ENABLE_PREVIEW_LAYOUT + wxStaticText* m_label_show{ nullptr }; wxComboCtrl* m_combochecklist_features { nullptr }; size_t m_combochecklist_features_pos { 0 }; -#endif // !ENABLE_PREVIEW_LAYOUT wxComboCtrl* m_combochecklist_options { nullptr }; +#endif // !ENABLE_PREVIEW_LAYOUT DynamicPrintConfig* m_config; BackgroundSlicingProcess* m_process; @@ -130,7 +128,9 @@ public: CustomGCodes, Shells, ToolMarker, +#if !ENABLE_PREVIEW_LAYOUT Legend +#endif // !ENABLE_PREVIEW_LAYOUT }; Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, @@ -158,7 +158,9 @@ public: bool is_loaded() const { return m_loaded; } +#if !ENABLE_PREVIEW_LAYOUT void update_bottom_toolbar(); +#endif // !ENABLE_PREVIEW_LAYOUT void update_moves_slider(); void enable_moves_slider(bool enable); void move_moves_slider(wxKeyEvent& evt); @@ -178,8 +180,8 @@ private: #if !ENABLE_PREVIEW_LAYOUT void on_choice_view_type(wxCommandEvent& evt); void on_combochecklist_features(wxCommandEvent& evt); -#endif // !ENABLE_PREVIEW_LAYOUT void on_combochecklist_options(wxCommandEvent& evt); +#endif // !ENABLE_PREVIEW_LAYOUT // Create/Update/Reset double slider on 3dPreview wxBoxSizer* create_layers_slider_sizer(); @@ -196,7 +198,9 @@ private: void on_layers_slider_scroll_changed(wxCommandEvent& event); void on_moves_slider_scroll_changed(wxCommandEvent& event); +#if !ENABLE_PREVIEW_LAYOUT wxString get_option_type_string(OptionType type) const; +#endif // !ENABLE_PREVIEW_LAYOUT }; } // namespace GUI diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 7bdfb15c71..e514a4f796 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -349,6 +349,42 @@ bool ImGuiWrapper::radio_button(const wxString &label, bool active) return ImGui::RadioButton(label_utf8.c_str(), active); } +#if ENABLE_PREVIEW_LAYOUT +bool ImGuiWrapper::draw_radio_button(const std::string& name, float size, bool active, + std::function draw_callback) +{ + ImGuiWindow& window = *ImGui::GetCurrentWindow(); + if (window.SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window.GetID(name.c_str()); + + const ImVec2 pos = window.DC.CursorPos; + const ImRect total_bb(pos, pos + ImVec2(size, size + style.FramePadding.y * 2.0f)); + ImGui::ItemSize(total_bb, style.FramePadding.y); + if (!ImGui::ItemAdd(total_bb, id)) + return false; + + bool hovered, held; + bool pressed = ImGui::ButtonBehavior(total_bb, id, &hovered, &held); + if (pressed) + ImGui::MarkItemEdited(id); + + if (hovered) + window.DrawList->AddRect({ pos.x - 1.0f, pos.y - 1.0f }, { pos.x + size + 1.0f, pos.y + size + 1.0f }, ImGui::GetColorU32(ImGuiCol_CheckMark)); + + if (active) + window.DrawList->AddRect(pos, { pos.x + size, pos.y + size }, ImGui::GetColorU32(ImGuiCol_CheckMark)); + + draw_callback(window, pos, size); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window.DC.LastItemStatusFlags); + return pressed; +} +#endif // ENABLE_PREVIEW_LAYOUT + bool ImGuiWrapper::image_button() { return false; diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 441d26ccc6..73fe59ad13 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -16,6 +16,9 @@ class wxString; class wxMouseEvent; class wxKeyEvent; +#if ENABLE_PREVIEW_LAYOUT +struct IMGUI_API ImGuiWindow; +#endif // ENABLE_PREVIEW_LAYOUT namespace Slic3r { namespace GUI { @@ -68,7 +71,10 @@ public: bool button(const wxString &label); bool button(const wxString& label, float width, float height); bool radio_button(const wxString &label, bool active); - bool image_button(); +#if ENABLE_PREVIEW_LAYOUT + bool draw_radio_button(const std::string& name, float size, bool active, std::function draw_callback); +#endif // ENABLE_PREVIEW_LAYOUT + bool image_button(); bool input_double(const std::string &label, const double &value, const std::string &format = "%.3f"); bool input_double(const wxString &label, const double &value, const std::string &format = "%.3f"); bool input_vec3(const std::string &label, const Vec3d &value, float width, const std::string &format = "%.3f"); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8b110e1819..106b4a87de 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1632,7 +1632,9 @@ struct Plater::priv bool init_view_toolbar(); bool init_collapse_toolbar(); +#if !ENABLE_PREVIEW_LAYOUT void update_preview_bottom_toolbar(); +#endif // !ENABLE_PREVIEW_LAYOUT void update_preview_moves_slider(); void enable_preview_moves_slider(bool enable); @@ -4400,10 +4402,12 @@ bool Plater::priv::init_collapse_toolbar() return true; } +#if !ENABLE_PREVIEW_LAYOUT void Plater::priv::update_preview_bottom_toolbar() { preview->update_bottom_toolbar(); } +#endif // !ENABLE_PREVIEW_LAYOUT void Plater::priv::update_preview_moves_slider() { @@ -6637,10 +6641,12 @@ GLToolbar& Plater::get_collapse_toolbar() return p->collapse_toolbar; } +#if !ENABLE_PREVIEW_LAYOUT void Plater::update_preview_bottom_toolbar() { p->update_preview_bottom_toolbar(); } +#endif // !ENABLE_PREVIEW_LAYOUT void Plater::update_preview_moves_slider() { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 564caac968..f48025ba84 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -345,7 +345,9 @@ public: const GLToolbar& get_collapse_toolbar() const; GLToolbar& get_collapse_toolbar(); +#if !ENABLE_PREVIEW_LAYOUT void update_preview_bottom_toolbar(); +#endif // !ENABLE_PREVIEW_LAYOUT void update_preview_moves_slider(); void enable_preview_moves_slider(bool enable); From 57a0b23a0756246c481f8500944ac482bc4b32ed Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 24 Sep 2021 11:57:29 +0200 Subject: [PATCH 08/27] Tech ENABLE_PREVIEW_LAYOUT - Avoid resetting the preview's horizontal slider when toggling options --- src/slic3r/GUI/GCodeViewer.cpp | 8 +++++++- src/slic3r/GUI/GCodeViewer.hpp | 6 ++++++ src/slic3r/GUI/GLCanvas3D.cpp | 9 +++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 4 ++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b901ca01ef..2e8bbfc9c6 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -712,14 +712,20 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: #endif // ENABLE_GCODE_VIEWER_STATISTICS // update buffers' render paths +#if ENABLE_PREVIEW_LAYOUT + refresh_render_paths(false, false); +#else refresh_render_paths(); +#endif // ENABLE_PREVIEW_LAYOUT log_memory_used("Refreshed G-code extrusion paths, "); } +#if !ENABLE_PREVIEW_LAYOUT void GCodeViewer::refresh_render_paths() { refresh_render_paths(false, false); } +#endif // !ENABLE_PREVIEW_LAYOUT void GCodeViewer::update_shells_color_by_extruder(const DynamicPrintConfig* config) { @@ -4089,7 +4095,7 @@ void GCodeViewer::render_legend(float& legend_height) unsigned int new_flags = set_flag(flags, flag, !active); set_options_visibility_from_flags(new_flags); - wxGetApp().plater()->get_current_canvas3D()->refresh_gcode_preview_render_paths(); + wxGetApp().plater()->get_current_canvas3D()->refresh_gcode_preview_render_paths(true, true); wxGetApp().plater()->update_preview_moves_slider(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 6c164f5e8f..15b8d453c6 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -812,7 +812,11 @@ public: void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); // recalculate ranges in dependence of what is visible and sets tool/print colors void refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); +#if ENABLE_PREVIEW_LAYOUT + void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; +#else void refresh_render_paths(); +#endif // ENABLE_PREVIEW_LAYOUT void update_shells_color_by_extruder(const DynamicPrintConfig* config); void reset(); @@ -857,7 +861,9 @@ public: private: void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); +#if !ENABLE_PREVIEW_LAYOUT void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; +#endif // !ENABLE_PREVIEW_LAYOUT void render_toolpaths(); void render_shells(); void render_legend(float& legend_height); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 45d1900808..5ebf57c6ce 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2100,12 +2100,21 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, request_extra_frame(); } +#if ENABLE_PREVIEW_LAYOUT +void GLCanvas3D::refresh_gcode_preview_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) +{ + m_gcode_viewer.refresh_render_paths(keep_sequential_current_first, keep_sequential_current_last); + set_as_dirty(); + request_extra_frame(); +} +#else void GLCanvas3D::refresh_gcode_preview_render_paths() { m_gcode_viewer.refresh_render_paths(); set_as_dirty(); request_extra_frame(); } +#endif // ENABLE_PREVIEW_LAYOUT void GLCanvas3D::load_sla_preview() { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e03c4a71db..ad9398ae65 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -721,7 +721,11 @@ public: void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); void load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); +#if ENABLE_PREVIEW_LAYOUT + void refresh_gcode_preview_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last); +#else void refresh_gcode_preview_render_paths(); +#endif // ENABLE_PREVIEW_LAYOUT void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); } GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); } void load_sla_preview(); From d458de601b51aa06886507d88b4d26ff469885dd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 24 Sep 2021 12:33:26 +0200 Subject: [PATCH 09/27] Tech ENABLE_PREVIEW_LAYOUT - Fixed legend layout for tool view --- src/slic3r/GUI/GCodeViewer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 2e8bbfc9c6..b65d401f73 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3538,6 +3538,8 @@ void GCodeViewer::render_legend(float& legend_height) // extrusion paths section -> title if (m_view_type == EViewType::FeatureType) append_headers({ _u8L(""), _u8L("Time"), _u8L("Percentage"), _u8L("Used filament") }, offsets); + else if (m_view_type == EViewType::Tool) + append_headers({ _u8L(""), _u8L("Used filament"), _u8L(""), _u8L("") }, offsets); else ImGui::Separator(); #else @@ -4121,6 +4123,7 @@ void GCodeViewer::render_legend(float& legend_height) ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); + ImGui::Spacing(); toggle_button(Preview::OptionType::Travel, _u8L("Travel"), [line_icon](ImGuiWindow& window, const ImVec2& pos, float size) { line_icon(window, pos, size, Travel_Colors[0]); }); From 1a95169466614af21707f4928097af2d49f86403 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Sep 2021 11:56:55 +0200 Subject: [PATCH 10/27] Tech ENABLE_PREVIEW_LAYOUT - Fixed legend width when moving the application to another monitor --- src/slic3r/GUI/GCodeViewer.cpp | 14 ++++++++++++-- src/slic3r/GUI/GCodeViewer.hpp | 17 +++++++++++++++++ src/slic3r/GUI/GLCanvas3D.cpp | 3 +++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b65d401f73..0ab4f80d6a 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -758,6 +758,9 @@ void GCodeViewer::reset() #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.reset_all(); #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_PREVIEW_LAYOUT + m_legend_resizer.reset(); +#endif // ENABLE_PREVIEW_LAYOUT } void GCodeViewer::render() @@ -3513,8 +3516,11 @@ void GCodeViewer::render_legend(float& legend_height) bool view_type_changed = false; int old_view_type = static_cast(get_view_type()); int view_type = old_view_type; - ImGuiStyle& style = ImGui::GetStyle(); - ImGui::PushItemWidth(ImGui::GetWindowWidth() - style.ItemSpacing.x - 2.0f * style.FramePadding.x); + + ImGui::SetNextItemWidth(m_legend_resizer.dirty ? 0.0f : -1.0f); + if (m_legend_resizer.last_width > ImGui::GetWindowWidth()) + m_legend_resizer.dirty = false; + ImGui::PushStyleColor(ImGuiCol_FrameBg, { 0.1f, 0.1f, 0.1f, 0.8f }); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, { 0.2f, 0.2f, 0.2f, 0.8f }); imgui.combo("", { _u8L("Feature type"), @@ -4182,6 +4188,10 @@ void GCodeViewer::render_legend(float& legend_height) const float mid_x = 0.5f * (pos.x + pos.x + size); window.DrawList->AddRectFilled({ mid_x - 0.09375f * size, p1.y - 0.25f * size }, { mid_x + 0.09375f * size, pos.y + margin }, color); }); + + m_legend_resizer.last_width = ImGui::GetCurrentWindow()->DC.CursorPosPrevLine.x + ImGui::GetStyle().WindowPadding.x; + if (m_legend_resizer.last_width < ImGui::GetWindowWidth()) + m_legend_resizer.dirty = true; #endif // ENABLE_PREVIEW_LAYOUT legend_height = ImGui::GetCurrentWindow()->Size.y; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 15b8d453c6..b002826d14 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -793,6 +793,19 @@ private: Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; +#if ENABLE_PREVIEW_LAYOUT + struct LegendResizer + { + bool dirty{ true }; + float last_width{ 0.0f }; + + void reset() { + dirty = true; + last_width = 0.0f; + } + }; + LegendResizer m_legend_resizer; +#endif // ENABLE_PREVIEW_LAYOUT PrintEstimatedStatistics m_print_statistics; PrintEstimatedStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedStatistics::ETimeMode::Normal }; #if ENABLE_GCODE_VIEWER_STATISTICS @@ -858,6 +871,10 @@ public: std::vector& get_custom_gcode_per_print_z() { return m_custom_gcode_per_print_z; } size_t get_extruders_count() { return m_extruders_count; } +#if ENABLE_PREVIEW_LAYOUT + void invalidate_legend() { m_legend_resizer.reset(); } +#endif // ENABLE_PREVIEW_LAYOUT + private: void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5ebf57c6ce..57d338600d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3741,6 +3741,9 @@ void GLCanvas3D::set_cursor(ECursorType type) void GLCanvas3D::msw_rescale() { +#if ENABLE_PREVIEW_LAYOUT + m_gcode_viewer.invalidate_legend(); +#endif // ENABLE_PREVIEW_LAYOUT } void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar() From c963c3c80105f71b9a001e8c066cd7df9c14cadf Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Sep 2021 12:35:53 +0200 Subject: [PATCH 11/27] Follow-up of 1a95169466614af21707f4928097af2d49f86403 - Fixed legend resizer --- src/slic3r/GUI/GCodeViewer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 0ab4f80d6a..8897ffddf7 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3517,8 +3517,9 @@ void GCodeViewer::render_legend(float& legend_height) int old_view_type = static_cast(get_view_type()); int view_type = old_view_type; - ImGui::SetNextItemWidth(m_legend_resizer.dirty ? 0.0f : -1.0f); - if (m_legend_resizer.last_width > ImGui::GetWindowWidth()) + if (!m_legend_resizer.dirty) + ImGui::SetNextItemWidth(-1.0f); + if (m_legend_resizer.last_width >= ImGui::GetWindowWidth()) m_legend_resizer.dirty = false; ImGui::PushStyleColor(ImGuiCol_FrameBg, { 0.1f, 0.1f, 0.1f, 0.8f }); From e088a9fc363562ff233076aa0405b6fe73d39f1d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Sep 2021 13:30:18 +0200 Subject: [PATCH 12/27] Tech ENABLE_PREVIEW_LAYOUT - View type combo popup has now adaptive height --- src/slic3r/GUI/GCodeViewer.cpp | 4 ++-- src/slic3r/GUI/ImGuiWrapper.cpp | 4 ++-- src/slic3r/GUI/ImGuiWrapper.hpp | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 8897ffddf7..5ec802c5e5 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3532,9 +3532,9 @@ void GCodeViewer::render_legend(float& legend_height) _u8L("Temperature (°C)"), _u8L("Volumetric flow rate (mm³/s)"), _u8L("Tool"), - _u8L("Color Print") }, view_type); + _u8L("Color Print") }, view_type, ImGuiComboFlags_HeightLargest); ImGui::PopStyleColor(2); - + if (old_view_type != view_type) { set_view_type(static_cast(view_type)); wxGetApp().plater()->set_keep_current_preview_type(true); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index e514a4f796..e2bd87a2a0 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -477,7 +477,7 @@ bool ImGuiWrapper::slider_float(const wxString& label, float* v, float v_min, fl return this->slider_float(label_utf8.c_str(), v, v_min, v_max, format, power, clamp); } -bool ImGuiWrapper::combo(const wxString& label, const std::vector& options, int& selection) +bool ImGuiWrapper::combo(const wxString& label, const std::vector& options, int& selection, ImGuiComboFlags flags) { // this is to force the label to the left of the widget: #if ENABLE_PREVIEW_LAYOUT @@ -493,7 +493,7 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector& bool res = false; const char *selection_str = selection < int(options.size()) && selection >= 0 ? options[selection].c_str() : ""; - if (ImGui::BeginCombo("", selection_str)) { + if (ImGui::BeginCombo("", selection_str, flags)) { for (int i = 0; i < (int)options.size(); i++) { if (ImGui::Selectable(options[i].c_str(), i == selection)) { selection_out = i; diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 73fe59ad13..8d464a202e 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -91,7 +91,8 @@ public: bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true); bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true); - bool combo(const wxString& label, const std::vector& options, int& selection); // Use -1 to not mark any option as selected + // Use selection = -1 to not mark any option as selected + bool combo(const wxString& label, const std::vector& options, int& selection, ImGuiComboFlags flags = 0); bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected, int& mouse_wheel); void search_list(const ImVec2& size, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str, Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel, bool is_localized); From b4423aa9542ff24acb06a0cf42793584020795a8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 30 Sep 2021 08:35:36 +0200 Subject: [PATCH 13/27] Fixes required after merge with branch et_layer_time_preview --- src/libslic3r/Technologies.hpp | 4 ++-- src/slic3r/GUI/GCodeViewer.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index d89b995125..ee64ebab41 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -62,8 +62,6 @@ #define ENABLE_RELOAD_FROM_DISK_REPLACE_FILE (1 && ENABLE_2_4_0_ALPHA2) // Enable fixing the synchronization of seams with the horizontal slider in preview #define ENABLE_FIX_SEAMS_SYNCH (1 && ENABLE_2_4_0_ALPHA2) -// Enable changes in preview layout -#define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_4_0_ALPHA2) //==================== @@ -73,6 +71,8 @@ // Enable fixing loading of gcode files generated with SuperSlicer in GCodeViewer #define ENABLE_FIX_SUPERSLICER_GCODE_IMPORT (1 && ENABLE_2_4_0_ALPHA3) +// Enable changes in preview layout +#define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_4_0_ALPHA3) // Enable coloring of toolpaths in preview by layer time #define ENABLE_PREVIEW_LAYER_TIME (1 && ENABLE_2_4_0_ALPHA3) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index aa9d321105..a97a2ab35b 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3683,6 +3683,10 @@ void GCodeViewer::render_legend(float& legend_height) _u8L("Fan speed (%)"), _u8L("Temperature (°C)"), _u8L("Volumetric flow rate (mm³/s)"), +#if ENABLE_PREVIEW_LAYER_TIME + _u8L("Layer time (linear)"), + _u8L("Layer time (logarithmic)"), +#endif // ENABLE_PREVIEW_LAYER_TIME _u8L("Tool"), _u8L("Color Print") }, view_type, ImGuiComboFlags_HeightLargest); ImGui::PopStyleColor(2); @@ -3746,7 +3750,7 @@ void GCodeViewer::render_legend(float& legend_height) visible, times[i], percents[i], max_percent, offsets, used_filaments_m[i], used_filaments_g[i], [this, role, visible]() { m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths - refresh_render_paths(); + refresh_render_paths(false, false); wxGetApp().plater()->update_preview_moves_slider(); wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); #if !ENABLE_PREVIEW_LAYOUT @@ -4225,7 +4229,7 @@ void GCodeViewer::render_legend(float& legend_height) m_time_estimate_mode = mode; #if ENABLE_PREVIEW_LAYER_TIME if (m_view_type == EViewType::LayerTimeLinear || m_view_type == EViewType::LayerTimeLogarithmic) - refresh_render_paths(); + refresh_render_paths(false, false); #endif // ENABLE_PREVIEW_LAYER_TIME wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); From cd05e8f6cb4c0cf6d421eb820bea936369722ec3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 5 Oct 2021 14:13:35 +0200 Subject: [PATCH 14/27] Tech ENABLE_PREVIEW_LAYOUT - Other fixes related to legend size when moving the application to another monitor --- src/slic3r/GUI/GCodeViewer.cpp | 17 +++++++++-------- src/slic3r/GUI/GCodeViewer.hpp | 7 +------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index a97a2ab35b..51dc892f8b 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3671,8 +3671,6 @@ void GCodeViewer::render_legend(float& legend_height) if (!m_legend_resizer.dirty) ImGui::SetNextItemWidth(-1.0f); - if (m_legend_resizer.last_width >= ImGui::GetWindowWidth()) - m_legend_resizer.dirty = false; ImGui::PushStyleColor(ImGuiCol_FrameBg, { 0.1f, 0.1f, 0.1f, 0.8f }); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, { 0.2f, 0.2f, 0.2f, 0.8f }); @@ -3789,7 +3787,7 @@ void GCodeViewer::render_legend(float& legend_height) total_items += color_print_ranges(i, custom_gcode_per_print_z).size(); } - const bool need_scrollable = static_cast(total_items) * (icon_size + ImGui::GetStyle().ItemSpacing.y) > child_height; + const bool need_scrollable = static_cast(total_items) * icon_size + (static_cast(total_items) - 1.0f) * ImGui::GetStyle().ItemSpacing.y > child_height; // add scrollable region, if needed if (need_scrollable) @@ -3999,7 +3997,7 @@ void GCodeViewer::render_legend(float& legend_height) ImGui::Spacing(); append_headers({ _u8L("Event"), _u8L("Remaining time"), _u8L("Duration"), _u8L("Used filament") }, offsets); - const bool need_scrollable = static_cast(partial_times.size()) * (icon_size + ImGui::GetStyle().ItemSpacing.y) > child_height; + const bool need_scrollable = static_cast(partial_times.size()) * icon_size + (static_cast(partial_times.size()) - 1.0f) * ImGui::GetStyle().ItemSpacing.y > child_height; if (need_scrollable) // add scrollable region ImGui::BeginChild("events", { -1.0f, child_height }, false); @@ -4356,12 +4354,15 @@ void GCodeViewer::render_legend(float& legend_height) window.DrawList->AddRectFilled({ mid_x - 0.09375f * size, p1.y - 0.25f * size }, { mid_x + 0.09375f * size, pos.y + margin }, color); }); - m_legend_resizer.last_width = ImGui::GetCurrentWindow()->DC.CursorPosPrevLine.x + ImGui::GetStyle().WindowPadding.x; - if (m_legend_resizer.last_width < ImGui::GetWindowWidth()) - m_legend_resizer.dirty = true; + bool size_dirty = !ImGui::GetCurrentWindow()->ScrollbarY && ImGui::CalcWindowNextAutoFitSize(ImGui::GetCurrentWindow()).x != ImGui::GetWindowWidth(); + if (m_legend_resizer.dirty || size_dirty != m_legend_resizer.dirty) { + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + } + m_legend_resizer.dirty = size_dirty; #endif // ENABLE_PREVIEW_LAYOUT - legend_height = ImGui::GetCurrentWindow()->Size.y; + legend_height = ImGui::GetWindowHeight(); imgui.end(); ImGui::PopStyleVar(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e8c036e333..e1753576ad 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -822,12 +822,7 @@ private: struct LegendResizer { bool dirty{ true }; - float last_width{ 0.0f }; - - void reset() { - dirty = true; - last_width = 0.0f; - } + void reset() { dirty = true; } }; LegendResizer m_legend_resizer; #endif // ENABLE_PREVIEW_LAYOUT From c18280016ab6a1f1227d782a527a7a59df0d8d5d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 5 Oct 2021 14:27:12 +0200 Subject: [PATCH 15/27] Tech ENABLE_PREVIEW_LAYOUT - Follow-up of 9a24b08e2890481f25941ba5e9a8a59fcb315d63 - Port of the into fix the tech --- src/slic3r/GUI/GUI_Preview.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 4d84454eb6..1e738aa7c5 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -980,10 +980,9 @@ void Preview::load_print_as_fff(bool keep_z_range) (number_extruders > 1) ? GCodeViewer::EViewType::Tool : GCodeViewer::EViewType::FeatureType; if (choice != gcode_view_type) { m_canvas->set_gcode_view_preview_type(choice); - if (wxGetApp().is_gcode_viewer()) { + if (wxGetApp().is_gcode_viewer()) m_keep_current_preview_type = true; - refresh_print(); - } + refresh_print(); } #else const wxString choice = !gcodes.empty() ? From e02a25cf1e6ed07ef8b30259a875b907d205110f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 5 Oct 2021 15:28:43 +0200 Subject: [PATCH 16/27] Follow-up of 57a0b23a0756246c481f8500944ac482bc4b32ed - Tech ENABLE_PREVIEW_LAYOUT - Fixed logic to avoid resetting the preview's horizontal slider when toggling options --- src/slic3r/GUI/GCodeViewer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 5a17ae7f35..9c0550495d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4276,7 +4276,9 @@ void GCodeViewer::render_legend(float& legend_height) unsigned int new_flags = set_flag(flags, flag, !active); set_options_visibility_from_flags(new_flags); - wxGetApp().plater()->get_current_canvas3D()->refresh_gcode_preview_render_paths(true, true); + bool keep_first = m_sequential_view.current.first != m_sequential_view.global.first; + bool keep_last = m_sequential_view.current.last != m_sequential_view.global.last; + wxGetApp().plater()->get_current_canvas3D()->refresh_gcode_preview_render_paths(keep_first, keep_last); wxGetApp().plater()->update_preview_moves_slider(); } From 077abe117a24fa8e3bf03590702afa368cf31573 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 6 Oct 2021 15:49:25 +0200 Subject: [PATCH 17/27] Port of 2afdc66dfb84f512a3f72b0a18ceb51873d779c5 and dbad87fb42343a8c9eaf51897bfe316a82c344d7 into tech ENABLE_PREVIEW_LAYOUT --- src/slic3r/GUI/GCodeViewer.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 9c0550495d..9086a86060 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4276,9 +4276,15 @@ void GCodeViewer::render_legend(float& legend_height) unsigned int new_flags = set_flag(flags, flag, !active); set_options_visibility_from_flags(new_flags); - bool keep_first = m_sequential_view.current.first != m_sequential_view.global.first; - bool keep_last = m_sequential_view.current.last != m_sequential_view.global.last; - wxGetApp().plater()->get_current_canvas3D()->refresh_gcode_preview_render_paths(keep_first, keep_last); + const unsigned int diff_flags = flags ^ new_flags; + if (m_view_type == GCodeViewer::EViewType::Feedrate && + (diff_flags & (1 << static_cast(Preview::OptionType::Travel))) != 0) + wxGetApp().plater()->refresh_print(); + else { + bool keep_first = m_sequential_view.current.first != m_sequential_view.global.first; + bool keep_last = m_sequential_view.current.last != m_sequential_view.global.last; + wxGetApp().plater()->get_current_canvas3D()->refresh_gcode_preview_render_paths(keep_first, keep_last); + } wxGetApp().plater()->update_preview_moves_slider(); } From 86636a906cc7977b0b2861d0045cfbde3b9018d9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 6 Oct 2021 15:55:14 +0200 Subject: [PATCH 18/27] Small refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 9086a86060..d76d4bed4d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4277,9 +4277,8 @@ void GCodeViewer::render_legend(float& legend_height) set_options_visibility_from_flags(new_flags); const unsigned int diff_flags = flags ^ new_flags; - if (m_view_type == GCodeViewer::EViewType::Feedrate && - (diff_flags & (1 << static_cast(Preview::OptionType::Travel))) != 0) - wxGetApp().plater()->refresh_print(); + if (m_view_type == GCodeViewer::EViewType::Feedrate && is_flag_set(diff_flags, static_cast(Preview::OptionType::Travel))) + wxGetApp().plater()->refresh_print(); else { bool keep_first = m_sequential_view.current.first != m_sequential_view.global.first; bool keep_last = m_sequential_view.current.last != m_sequential_view.global.last; From eee8d97f497fcfaa69763cfa316d070c430f07e9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 7 Oct 2021 14:07:33 +0200 Subject: [PATCH 19/27] Tech ENABLE_TRAVEL_TIME - Show estimated time for travel moves in legend when they are visible --- src/libslic3r/GCode/GCodeProcessor.cpp | 26 ++++++++++++++++++ src/libslic3r/GCode/GCodeProcessor.hpp | 13 +++++++++ src/libslic3r/Technologies.hpp | 13 +++++++-- src/slic3r/GUI/GCodeViewer.cpp | 37 +++++++++++++++++++++++--- 4 files changed, 83 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 9c90535c4e..4b38d15358 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -189,6 +189,9 @@ void GCodeProcessor::TimeMachine::reset() max_travel_acceleration = 0.0f; extrude_factor_override_percentage = 1.0f; time = 0.0f; +#if ENABLE_TRAVEL_TIME + travel_time = 0.0f; +#endif // ENABLE_TRAVEL_TIME stop_times = std::vector(); curr.reset(); prev.reset(); @@ -303,9 +306,17 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks) const TimeBlock& block = blocks[i]; float block_time = block.time(); time += block_time; +#if ENABLE_TRAVEL_TIME + if (block.move_type == EMoveType::Travel) + travel_time += block_time; + else + roles_time[static_cast(block.role)] += block_time; +#endif // ENABLE_TRAVEL_TIME gcode_time.cache += block_time; moves_time[static_cast(block.move_type)] += block_time; +#if !ENABLE_TRAVEL_TIME roles_time[static_cast(block.role)] += block_time; +#endif // !ENABLE_TRAVEL_TIME if (block.layer_id > 0) { if (block.layer_id >= layers_time.size()) { size_t curr_size = layers_time.size(); @@ -1327,6 +1338,18 @@ std::string GCodeProcessor::get_time_dhm(PrintEstimatedStatistics::ETimeMode mod return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)) : std::string("N/A"); } +#if ENABLE_TRAVEL_TIME +float GCodeProcessor::get_travel_time(PrintEstimatedStatistics::ETimeMode mode) const +{ + return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].travel_time : 0.0f; +} + +std::string GCodeProcessor::get_travel_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const +{ + return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].travel_time)) : std::string("N/A"); +} +#endif // ENABLE_TRAVEL_TIME + std::vector>> GCodeProcessor::get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const { std::vector>> ret; @@ -3332,6 +3355,9 @@ void GCodeProcessor::update_estimated_times_stats() auto update_mode = [this](PrintEstimatedStatistics::ETimeMode mode) { PrintEstimatedStatistics::Mode& data = m_result.print_statistics.modes[static_cast(mode)]; data.time = get_time(mode); +#if ENABLE_TRAVEL_TIME + data.travel_time = get_travel_time(mode); +#endif // ENABLE_TRAVEL_TIME data.custom_gcode_times = get_custom_gcode_times(mode, true); data.moves_times = get_moves_time(mode); data.roles_times = get_roles_time(mode); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index fce8882333..a4e6f4d2fa 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -44,6 +44,9 @@ namespace Slic3r { struct Mode { float time; +#if ENABLE_TRAVEL_TIME + float travel_time; +#endif // ENABLE_TRAVEL_TIME std::vector>> custom_gcode_times; std::vector> moves_times; std::vector> roles_times; @@ -51,6 +54,9 @@ namespace Slic3r { void reset() { time = 0.0f; +#if ENABLE_TRAVEL_TIME + travel_time = 0.0f; +#endif // ENABLE_TRAVEL_TIME custom_gcode_times.clear(); moves_times.clear(); roles_times.clear(); @@ -250,6 +256,9 @@ namespace Slic3r { float max_travel_acceleration; // mm/s^2 float extrude_factor_override_percentage; float time; // s +#if ENABLE_TRAVEL_TIME + float travel_time; // s +#endif // ENABLE_TRAVEL_TIME struct StopTime { unsigned int g1_line_id; @@ -593,6 +602,10 @@ namespace Slic3r { float get_time(PrintEstimatedStatistics::ETimeMode mode) const; std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const; +#if ENABLE_TRAVEL_TIME + float get_travel_time(PrintEstimatedStatistics::ETimeMode mode) const; + std::string get_travel_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const; +#endif // ENABLE_TRAVEL_TIME std::vector>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const; std::vector> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index ee64ebab41..7f78f5d1b8 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -71,10 +71,19 @@ // Enable fixing loading of gcode files generated with SuperSlicer in GCodeViewer #define ENABLE_FIX_SUPERSLICER_GCODE_IMPORT (1 && ENABLE_2_4_0_ALPHA3) + + +//==================== +// 2.4.0.alpha4 techs +//==================== +#define ENABLE_2_4_0_ALPHA4 1 + // Enable changes in preview layout -#define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_4_0_ALPHA3) +#define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_4_0_ALPHA4) // Enable coloring of toolpaths in preview by layer time -#define ENABLE_PREVIEW_LAYER_TIME (1 && ENABLE_2_4_0_ALPHA3) +#define ENABLE_PREVIEW_LAYER_TIME (1 && ENABLE_2_4_0_ALPHA4) +// Enable showing time estimate for travel moves in legend +#define ENABLE_TRAVEL_TIME (1 && ENABLE_2_4_0_ALPHA4) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index d76d4bed4d..32f73ddd8b 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3433,7 +3433,25 @@ void GCodeViewer::render_legend(float& legend_height) } else { imgui.text(label); +#if ENABLE_TRAVEL_TIME + if (!time.empty()) { + ImGui::SameLine(offsets[0]); + imgui.text(time); + ImGui::SameLine(offsets[1]); + pos = ImGui::GetCursorScreenPos(); + const float width = std::max(1.0f, percent_bar_size * percent / max_percent); + draw_list->AddRectFilled({ pos.x, pos.y + 2.0f }, { pos.x + width, pos.y + icon_size - 2.0f }, + ImGui::GetColorU32(ImGuiWrapper::COL_ORANGE_LIGHT)); + ImGui::Dummy({ percent_bar_size, icon_size }); + ImGui::SameLine(); + char buf[64]; + ::sprintf(buf, "%.1f%%", 100.0f * percent); + ImGui::TextUnformatted((percent > 0.0f) ? buf : ""); + } + else if (used_filament_m > 0.0) { +#else if (used_filament_m > 0.0) { +#endif // ENABLE_TRAVEL_TIME char buf[64]; ImGui::SameLine(offsets[0]); ::sprintf(buf, imperial_units ? "%.2f in" : "%.2f m", used_filament_m); @@ -3600,7 +3618,7 @@ void GCodeViewer::render_legend(float& legend_height) std::vector percents; std::vector used_filaments_m; std::vector used_filaments_g; - float max_percent = 0.0f; + float max_time_percent = 0.0f; if (m_view_type == EViewType::FeatureType) { // calculate offsets to align time/percentage data @@ -3611,7 +3629,7 @@ void GCodeViewer::render_legend(float& legend_height) auto [time, percent] = role_time_and_percent(role); times.push_back((time > 0.0f) ? short_time(get_time_dhms(time)) : ""); percents.push_back(percent); - max_percent = std::max(max_percent, percent); + max_time_percent = std::max(max_time_percent, percent); auto [used_filament_m, used_filament_g] = used_filament_per_role(role); used_filaments_m.push_back(used_filament_m); used_filaments_g.push_back(used_filament_g); @@ -3747,13 +3765,17 @@ void GCodeViewer::render_legend(float& legend_height) { case EViewType::FeatureType: { +#if ENABLE_TRAVEL_TIME + max_time_percent = std::max(max_time_percent, time_mode.travel_time / time_mode.time); +#endif // ENABLE_TRAVEL_TIME + for (size_t i = 0; i < m_roles.size(); ++i) { ExtrusionRole role = m_roles[i]; if (role >= erCount) continue; const bool visible = is_visible(role); append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], labels[i], - visible, times[i], percents[i], max_percent, offsets, used_filaments_m[i], used_filaments_g[i], [this, role, visible]() { + visible, times[i], percents[i], max_time_percent, offsets, used_filaments_m[i], used_filaments_g[i], [this, role, visible]() { m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths refresh_render_paths(false, false); @@ -3765,6 +3787,13 @@ void GCodeViewer::render_legend(float& legend_height) } ); } + +#if ENABLE_TRAVEL_TIME + if (m_buffers[buffer_id(EMoveType::Travel)].visible) + append_item(EItemType::Line, Travel_Colors[0], _u8L("Travel"), true, short_time(get_time_dhms(time_mode.travel_time)), + time_mode.travel_time / time_mode.time, max_time_percent, offsets, 0.0f, 0.0f); +#endif // ENABLE_TRAVEL_TIME + break; } case EViewType::Height: { append_range(m_extrusions.ranges.height, 3); break; } @@ -3783,7 +3812,7 @@ void GCodeViewer::render_legend(float& legend_height) for (unsigned char extruder_id : m_extruder_ids) { append_item(EItemType::Rect, m_tool_colors[extruder_id], _u8L("Extruder") + " " + std::to_string(extruder_id + 1), true, "", 0.0f, 0.0f, offsets, used_filaments_m[i], used_filaments_g[i]); - i++; + ++i; } break; } From 0d922b04af5e4df8f0a7c044d5f05ef4e1975990 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 14 Oct 2021 11:30:27 +0200 Subject: [PATCH 20/27] Tech ENABLE_PREVIEW_LAYOUT - Added menu item View/Show legend --- src/slic3r/GUI/GLCanvas3D.cpp | 12 +++++++----- src/slic3r/GUI/GLCanvas3D.hpp | 5 +++++ src/slic3r/GUI/KBShortcutsDialog.cpp | 2 +- src/slic3r/GUI/MainFrame.cpp | 11 +++++++++++ src/slic3r/GUI/Plater.cpp | 10 ++++++++++ src/slic3r/GUI/Plater.hpp | 5 +++++ 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ca31645c1e..8dc750d40e 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2422,14 +2422,16 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'i': { _update_camera_zoom(1.0); break; } case 'K': case 'k': { wxGetApp().plater()->get_camera().select_next_type(); m_dirty = true; break; } - case 'L': - case 'l': { - if (!m_main_toolbar.is_enabled()) { + case 'L': + case 'l': { + if (!m_main_toolbar.is_enabled()) { +#if ENABLE_PREVIEW_LAYOUT + show_legend(!is_legend_shown()); +#else m_gcode_viewer.enable_legend(!m_gcode_viewer.is_legend_enabled()); m_dirty = true; -#if !ENABLE_PREVIEW_LAYOUT wxGetApp().plater()->update_preview_bottom_toolbar(); -#endif // !ENABLE_PREVIEW_LAYOUT +#endif // ENABLE_PREVIEW_LAYOUT } break; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 10df84b35e..0987823376 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -820,6 +820,11 @@ public: bool are_labels_shown() const { return m_labels.is_shown(); } void show_labels(bool show) { m_labels.show(show); } +#if ENABLE_PREVIEW_LAYOUT + bool is_legend_shown() const { return m_gcode_viewer.is_legend_enabled(); } + void show_legend(bool show) { m_gcode_viewer.enable_legend(show); m_dirty = true; } +#endif // ENABLE_PREVIEW_LAYOUT + bool is_using_slope() const { return m_slope.is_used(); } void use_slope(bool use) { m_slope.use(use); } void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); } diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index d16161f890..992b0be137 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -223,7 +223,7 @@ void KBShortcutsDialog::fill_shortcuts() { "A", L("Horizontal slider - Move active thumb Left") }, { "D", L("Horizontal slider - Move active thumb Right") }, { "X", L("On/Off one layer mode of the vertical slider") }, - { "L", L("Show/Hide Legend and Estimated printing time") }, + { "L", L("Show/Hide legend") }, { "C", L("Show/Hide G-code window") }, }; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 799c4e7933..9f80874ac2 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1433,6 +1433,11 @@ void MainFrame::init_menubar_as_editor() append_menu_check_item(viewMenu, wxID_ANY, _L("Show &labels") + sep + "E", _L("Show object/instance labels in 3D scene"), [this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this, [this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this); +#if ENABLE_PREVIEW_LAYOUT + append_menu_check_item(viewMenu, wxID_ANY, _L("Show legen&d") + sep + "L", _L("Show legend in preview"), + [this](wxCommandEvent&) { m_plater->show_legend(!m_plater->is_legend_shown()); }, this, + [this]() { return m_plater->is_preview_shown(); }, [this]() { return m_plater->is_legend_shown(); }, this); +#endif // ENABLE_PREVIEW_LAYOUT append_menu_check_item(viewMenu, wxID_ANY, _L("&Collapse sidebar") + sep + "Shift+" + sep_space + "Tab", _L("Collapse sidebar"), [this](wxCommandEvent&) { m_plater->collapse_sidebar(!m_plater->is_sidebar_collapsed()); }, this, []() { return true; }, [this]() { return m_plater->is_sidebar_collapsed(); }, this); @@ -1550,6 +1555,12 @@ void MainFrame::init_menubar_as_gcodeviewer() if (m_plater != nullptr) { viewMenu = new wxMenu(); add_common_view_menu_items(viewMenu, this, std::bind(&MainFrame::can_change_view, this)); +#if ENABLE_PREVIEW_LAYOUT + viewMenu->AppendSeparator(); + append_menu_check_item(viewMenu, wxID_ANY, _L("Show legen&d") + sep + "L", _L("Show legend"), + [this](wxCommandEvent&) { m_plater->show_legend(!m_plater->is_legend_shown()); }, this, + [this]() { return m_plater->is_preview_shown(); }, [this]() { return m_plater->is_legend_shown(); }, this); +#endif // ENABLE_PREVIEW_LAYOUT } // helpmenu diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 52a84206b5..9aa3999663 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1667,6 +1667,11 @@ struct Plater::priv bool are_view3D_labels_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->are_labels_shown(); } void show_view3D_labels(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_labels(show); } +#if ENABLE_PREVIEW_LAYOUT + bool is_legend_shown() const { return (current_panel == preview) && preview->get_canvas3d()->is_legend_shown(); } + void show_legend(bool show) { if (current_panel == preview) preview->get_canvas3d()->show_legend(show); } +#endif // ENABLE_PREVIEW_LAYOUT + bool is_sidebar_collapsed() const { return sidebar->is_collapsed(); } void collapse_sidebar(bool collapse); @@ -5410,6 +5415,11 @@ bool Plater::is_view3D_shown() const { return p->is_view3D_shown(); } bool Plater::are_view3D_labels_shown() const { return p->are_view3D_labels_shown(); } void Plater::show_view3D_labels(bool show) { p->show_view3D_labels(show); } +#if ENABLE_PREVIEW_LAYOUT +bool Plater::is_legend_shown() const { return p->is_legend_shown(); } +void Plater::show_legend(bool show) { p->show_legend(show); } +#endif // ENABLE_PREVIEW_LAYOUT + bool Plater::is_sidebar_collapsed() const { return p->is_sidebar_collapsed(); } void Plater::collapse_sidebar(bool show) { p->collapse_sidebar(show); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index a595ab44ee..2370e09c87 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -187,6 +187,11 @@ public: bool are_view3D_labels_shown() const; void show_view3D_labels(bool show); +#if ENABLE_PREVIEW_LAYOUT + bool is_legend_shown() const; + void show_legend(bool show); +#endif // ENABLE_PREVIEW_LAYOUT + bool is_sidebar_collapsed() const; void collapse_sidebar(bool show); From 3b17cde53ff3928041ee706656e7b3b1f33b9f0a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 19 Oct 2021 13:36:20 +0200 Subject: [PATCH 21/27] Tech ENABLE_PREVIEW_LAYOUT - Collassable legend --- src/slic3r/GUI/GCodeViewer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 4af575e193..8aa5b0bffe 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3369,7 +3369,11 @@ void GCodeViewer::render_legend(float& legend_height) const float max_height = 0.75f * static_cast(cnv_size.get_height()); const float child_height = 0.3333f * max_height; ImGui::SetNextWindowSizeConstraints({ 0.0f, 0.0f }, { -1.0f, max_height }); +#if ENABLE_PREVIEW_LAYOUT + imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove); +#else imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); +#endif // ENABLE_PREVIEW_LAYOUT enum class EItemType : unsigned char { From a326c5b32024492497545bcb2f3a70dc446c08c7 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 12 Nov 2021 14:04:37 +0100 Subject: [PATCH 22/27] Tech ENABLE_LEGEND_TOOLBAR_ICONS - Toolbar items in legend using svn icons --- resources/icons/legend_colorchanges.svg | 157 +++++++++++++++++++++++ resources/icons/legend_customgcodes.svg | 71 +++++++++++ resources/icons/legend_deretract.svg | 107 ++++++++++++++++ resources/icons/legend_pauseprints.svg | 76 +++++++++++ resources/icons/legend_retract.svg | 110 ++++++++++++++++ resources/icons/legend_seams.svg | 45 +++++++ resources/icons/legend_shells.svg | 77 +++++++++++ resources/icons/legend_toolchanges.svg | 102 +++++++++++++++ resources/icons/legend_toolmarker.svg | 76 +++++++++++ resources/icons/legend_travel.svg | 163 ++++++++++++++++++++++++ resources/icons/legend_wipe.svg | 48 +++++++ src/imgui/imconfig.h | 11 ++ src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/GCodeViewer.cpp | 69 +++++++++- src/slic3r/GUI/ImGuiWrapper.cpp | 38 +++++- src/slic3r/GUI/ImGuiWrapper.hpp | 7 + 16 files changed, 1157 insertions(+), 2 deletions(-) create mode 100644 resources/icons/legend_colorchanges.svg create mode 100644 resources/icons/legend_customgcodes.svg create mode 100644 resources/icons/legend_deretract.svg create mode 100644 resources/icons/legend_pauseprints.svg create mode 100644 resources/icons/legend_retract.svg create mode 100644 resources/icons/legend_seams.svg create mode 100644 resources/icons/legend_shells.svg create mode 100644 resources/icons/legend_toolchanges.svg create mode 100644 resources/icons/legend_toolmarker.svg create mode 100644 resources/icons/legend_travel.svg create mode 100644 resources/icons/legend_wipe.svg diff --git a/resources/icons/legend_colorchanges.svg b/resources/icons/legend_colorchanges.svg new file mode 100644 index 0000000000..cb95ef4676 --- /dev/null +++ b/resources/icons/legend_colorchanges.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/legend_customgcodes.svg b/resources/icons/legend_customgcodes.svg new file mode 100644 index 0000000000..f363b39fdc --- /dev/null +++ b/resources/icons/legend_customgcodes.svg @@ -0,0 +1,71 @@ + + diff --git a/resources/icons/legend_deretract.svg b/resources/icons/legend_deretract.svg new file mode 100644 index 0000000000..4b636df9de --- /dev/null +++ b/resources/icons/legend_deretract.svg @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/legend_pauseprints.svg b/resources/icons/legend_pauseprints.svg new file mode 100644 index 0000000000..954bc00e97 --- /dev/null +++ b/resources/icons/legend_pauseprints.svg @@ -0,0 +1,76 @@ + + diff --git a/resources/icons/legend_retract.svg b/resources/icons/legend_retract.svg new file mode 100644 index 0000000000..494e2f7286 --- /dev/null +++ b/resources/icons/legend_retract.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/legend_seams.svg b/resources/icons/legend_seams.svg new file mode 100644 index 0000000000..724414119d --- /dev/null +++ b/resources/icons/legend_seams.svg @@ -0,0 +1,45 @@ + + + + + + + diff --git a/resources/icons/legend_shells.svg b/resources/icons/legend_shells.svg new file mode 100644 index 0000000000..b0a93effb2 --- /dev/null +++ b/resources/icons/legend_shells.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + diff --git a/resources/icons/legend_toolchanges.svg b/resources/icons/legend_toolchanges.svg new file mode 100644 index 0000000000..e6c195b110 --- /dev/null +++ b/resources/icons/legend_toolchanges.svg @@ -0,0 +1,102 @@ + + diff --git a/resources/icons/legend_toolmarker.svg b/resources/icons/legend_toolmarker.svg new file mode 100644 index 0000000000..be0c80bbb7 --- /dev/null +++ b/resources/icons/legend_toolmarker.svg @@ -0,0 +1,76 @@ + + diff --git a/resources/icons/legend_travel.svg b/resources/icons/legend_travel.svg new file mode 100644 index 0000000000..553e90a743 --- /dev/null +++ b/resources/icons/legend_travel.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/legend_wipe.svg b/resources/icons/legend_wipe.svg new file mode 100644 index 0000000000..9dbc9a6556 --- /dev/null +++ b/resources/icons/legend_wipe.svg @@ -0,0 +1,48 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h index e95ae3adfa..4f82a1f4c3 100644 --- a/src/imgui/imconfig.h +++ b/src/imgui/imconfig.h @@ -155,6 +155,17 @@ namespace ImGui const wchar_t ClippyMarker = 0x2602; const wchar_t InfoMarker = 0x2603; const wchar_t SliderFloatEditBtnIcon = 0x2604; + const wchar_t LegendTravel = 0x2605; + const wchar_t LegendWipe = 0x2606; + const wchar_t LegendRetract = 0x2607; + const wchar_t LegendDeretract = 0x2608; + const wchar_t LegendSeams = 0x2609; + const wchar_t LegendToolChanges = 0x2610; + const wchar_t LegendColorChanges = 0x2611; + const wchar_t LegendPausePrints = 0x2612; + const wchar_t LegendCustomGCodes = 0x2613; + const wchar_t LegendShells = 0x2614; + const wchar_t LegendToolMarker = 0x2615; // void MyFunction(const char* name, const MyMatrix44& v); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c628ae9647..dfaba9c71e 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -96,6 +96,8 @@ #define ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT (1 && ENABLE_2_4_0_BETA2) // Enable changes in preview layout #define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_4_0_BETA2) +// Enable drawing the items in legend toolbar using icons +#define ENABLE_LEGEND_TOOLBAR_ICONS (1 && ENABLE_PREVIEW_LAYOUT) // Enable coloring of toolpaths in preview by layer time #define ENABLE_PREVIEW_LAYER_TIME (1 && ENABLE_2_4_0_BETA2) // Enable showing time estimate for travel moves in legend diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 0170191af3..0bbc7e8a0c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4407,47 +4407,108 @@ void GCodeViewer::render_legend(float& legend_height) const float margin = 3.0f; window.DrawList->AddLine({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin, pos.y + margin }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); }; +#if ENABLE_LEGEND_TOOLBAR_ICONS + auto image_icon = [&imgui](ImGuiWindow& window, const ImVec2& pos, float size, const wchar_t& icon_id) { + ImGuiIO& io = ImGui::GetIO(); + const ImTextureID tex_id = io.Fonts->TexID; + const float tex_w = static_cast(io.Fonts->TexWidth); + const float tex_h = static_cast(io.Fonts->TexHeight); + const ImFontAtlas::CustomRect* const rect = imgui.GetTextureCustomRect(icon_id); + const ImVec2 uv0 = { static_cast(rect->X) / tex_w, static_cast(rect->Y) / tex_h }; + const ImVec2 uv1 = { static_cast(rect->X + rect->Width) / tex_w, static_cast(rect->Y + rect->Height) / tex_h }; + window.DrawList->AddImage(tex_id, pos, { pos.x + size, pos.y + size }, uv0, uv1, ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 1.0f })); + }; +#endif // ENABLE_LEGEND_TOOLBAR_ICONS ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); ImGui::Spacing(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::Travel, _u8L("Travel"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendTravel); +#else toggle_button(Preview::OptionType::Travel, _u8L("Travel"), [line_icon](ImGuiWindow& window, const ImVec2& pos, float size) { line_icon(window, pos, size, Travel_Colors[0]); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::Wipe, _u8L("Wipe"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendWipe); +#else toggle_button(Preview::OptionType::Wipe, _u8L("Wipe"), [line_icon](ImGuiWindow& window, const ImVec2& pos, float size) { line_icon(window, pos, size, Wipe_Color); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::Retractions, _u8L("Retractions"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendRetract); +#else toggle_button(Preview::OptionType::Retractions, _u8L("Retractions"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { - circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::Retractions)]); + circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::Retractions)]); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::Unretractions, _u8L("Deretractions"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendDeretract); +#else toggle_button(Preview::OptionType::Unretractions, _u8L("Deretractions"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::Unretractions)]); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::Seams, _u8L("Seams"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendSeams); +#else toggle_button(Preview::OptionType::Seams, _u8L("Seams"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::Seams)]); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::ToolChanges, _u8L("Tool changes"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendToolChanges); +#else toggle_button(Preview::OptionType::ToolChanges, _u8L("Tool changes"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::ToolChanges)]); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::ColorChanges, _u8L("Color changes"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendColorChanges); +#else toggle_button(Preview::OptionType::ColorChanges, _u8L("Color changes"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::ColorChanges)]); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::PausePrints, _u8L("Print pauses"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendPausePrints); +#else toggle_button(Preview::OptionType::PausePrints, _u8L("Print pauses"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::PausePrints)]); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::CustomGCodes, _u8L("Custom G-codes"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendCustomGCodes); +#else toggle_button(Preview::OptionType::CustomGCodes, _u8L("Custom G-codes"), [circle_icon](ImGuiWindow& window, const ImVec2& pos, float size) { circle_icon(window, pos, size, Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::Shells, _u8L("Shells"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendShells); +#else toggle_button(Preview::OptionType::Shells, _u8L("Shells"), [](ImGuiWindow& window, const ImVec2& pos, float size) { const ImU32 color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 1.0f }); const float margin = 3.0f; @@ -4458,8 +4519,13 @@ void GCodeViewer::render_legend(float& legend_height) window.DrawList->AddLine({ pos.x + size - margin - proj, pos.y + size - margin }, { pos.x + size - margin, pos.y + size - margin - proj }, color); window.DrawList->AddLine({ pos.x + margin + proj, pos.y + margin }, { pos.x + size - margin, pos.y + margin }, color); window.DrawList->AddLine({ pos.x + size - margin, pos.y + margin }, { pos.x + size - margin, pos.y + size - margin - proj }, color); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); ImGui::SameLine(); +#if ENABLE_LEGEND_TOOLBAR_ICONS + toggle_button(Preview::OptionType::ToolMarker, _u8L("Tool marker"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) { + image_icon(window, pos, size, ImGui::LegendToolMarker); +#else toggle_button(Preview::OptionType::ToolMarker, _u8L("Tool marker"), [](ImGuiWindow& window, const ImVec2& pos, float size) { const ImU32 color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.8f }); const float margin = 3.0f; @@ -4469,6 +4535,7 @@ void GCodeViewer::render_legend(float& legend_height) window.DrawList->AddTriangleFilled(p1, p2, p3, color); const float mid_x = 0.5f * (pos.x + pos.x + size); window.DrawList->AddRectFilled({ mid_x - 0.09375f * size, p1.y - 0.25f * size }, { mid_x + 0.09375f * size, pos.y + margin }, color); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }); bool size_dirty = !ImGui::GetCurrentWindow()->ScrollbarY && ImGui::CalcWindowNextAutoFitSize(ImGui::GetCurrentWindow()).x != ImGui::GetWindowWidth(); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 92401f0acd..058d8ef20c 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -53,8 +53,21 @@ static const std::map font_icons = { {ImGui::PreferencesButton , "notification_preferences" }, {ImGui::PreferencesHoverButton , "notification_preferences_hover"}, #if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT - {ImGui::SliderFloatEditBtnIcon, "edit_button" }, + {ImGui::SliderFloatEditBtnIcon , "edit_button" }, #endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT +#if ENABLE_LEGEND_TOOLBAR_ICONS + {ImGui::LegendTravel , "legend_travel" }, + {ImGui::LegendWipe , "legend_wipe" }, + {ImGui::LegendRetract , "legend_retract" }, + {ImGui::LegendDeretract , "legend_deretract" }, + {ImGui::LegendSeams , "legend_seams" }, + {ImGui::LegendToolChanges , "legend_toolchanges" }, + {ImGui::LegendColorChanges , "legend_colorchanges" }, + {ImGui::LegendPausePrints , "legend_pauseprints" }, + {ImGui::LegendCustomGCodes , "legend_customgcodes" }, + {ImGui::LegendShells , "legend_shells" }, + {ImGui::LegendToolMarker , "legend_toolmarker" }, +#endif // ENABLE_LEGEND_TOOLBAR_ICONS }; static const std::map font_icons_large = { {ImGui::CloseNotifButton , "notification_close" }, @@ -1052,6 +1065,14 @@ bool ImGuiWrapper::want_any_input() const return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput; } +#if ENABLE_LEGEND_TOOLBAR_ICONS +ImFontAtlasCustomRect* ImGuiWrapper::GetTextureCustomRect(const wchar_t& tex_id) +{ + auto item = m_custom_glyph_rects_ids.find(tex_id); + return (item != m_custom_glyph_rects_ids.end()) ? ImGui::GetIO().Fonts->GetCustomRectByIndex(m_custom_glyph_rects_ids[tex_id]) : nullptr; +} +#endif // ENABLE_LEGEND_TOOLBAR_ICONS + #ifdef __APPLE__ static const ImWchar ranges_keyboard_shortcuts[] = { @@ -1140,12 +1161,27 @@ void ImGuiWrapper::init_font(bool compress) int rect_id = io.Fonts->CustomRects.Size; // id of the rectangle added next // add rectangles for the icons to the font atlas +#if ENABLE_LEGEND_TOOLBAR_ICONS + for (auto& icon : font_icons) { + m_custom_glyph_rects_ids[icon.first] = + io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz, icon_sz, 3.0 * font_scale + icon_sz); + } + for (auto& icon : font_icons_large) { + m_custom_glyph_rects_ids[icon.first] = + io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 2, icon_sz * 2, 3.0 * font_scale + icon_sz * 2); + } + for (auto& icon : font_icons_extra_large) { + m_custom_glyph_rects_ids[icon.first] = + io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 4, icon_sz * 4, 3.0 * font_scale + icon_sz * 4); +} +#else for (auto& icon : font_icons) io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz, icon_sz, 3.0 * font_scale + icon_sz); for (auto& icon : font_icons_large) io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 2, icon_sz * 2, 3.0 * font_scale + icon_sz * 2); for (auto& icon : font_icons_extra_large) io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 4, icon_sz * 4, 3.0 * font_scale + icon_sz * 4); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS // Build texture atlas unsigned char* pixels; diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 8c17ca183d..102a1537f7 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -39,6 +39,9 @@ class ImGuiWrapper #if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT bool m_requires_extra_frame{ false }; #endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT +#if ENABLE_LEGEND_TOOLBAR_ICONS + std::map m_custom_glyph_rects_ids; +#endif // ENABLE_LEGEND_TOOLBAR_ICONS std::string m_clipboard_text; public: @@ -132,6 +135,10 @@ public: void reset_requires_extra_frame() { m_requires_extra_frame = false; } #endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT +#if ENABLE_LEGEND_TOOLBAR_ICONS + ImFontAtlasCustomRect* GetTextureCustomRect(const wchar_t& tex_id); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS + static const ImVec4 COL_GREY_DARK; static const ImVec4 COL_GREY_LIGHT; static const ImVec4 COL_ORANGE_DARK; From 6d89b22a5a37f38e3daa3eeaee262e963d0503db Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 15 Nov 2021 08:45:13 +0100 Subject: [PATCH 23/27] Tech ENABLE_LEGEND_TOOLBAR_ICONS - New icons for legend toolbar --- resources/icons/legend_toolchanges.svg | 122 ++++--------------------- resources/icons/legend_wipe.svg | 60 +++--------- 2 files changed, 34 insertions(+), 148 deletions(-) diff --git a/resources/icons/legend_toolchanges.svg b/resources/icons/legend_toolchanges.svg index e6c195b110..b6ed4c8a66 100644 --- a/resources/icons/legend_toolchanges.svg +++ b/resources/icons/legend_toolchanges.svg @@ -1,102 +1,20 @@ - - + + + + + + + + + + + + + + diff --git a/resources/icons/legend_wipe.svg b/resources/icons/legend_wipe.svg index 9dbc9a6556..decfcd6011 100644 --- a/resources/icons/legend_wipe.svg +++ b/resources/icons/legend_wipe.svg @@ -1,48 +1,16 @@ - - + + + + + + + + + + - - Svg Vector Icons : http://www.onlinewebfonts.com/icon - From b9c99ab27b2c1926c78f052ede313c5e2a522733 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 23 Nov 2021 08:32:55 +0100 Subject: [PATCH 24/27] New icon for legend toolbar --- resources/icons/legend_toolmarker.svg | 79 +-------------------------- 1 file changed, 3 insertions(+), 76 deletions(-) diff --git a/resources/icons/legend_toolmarker.svg b/resources/icons/legend_toolmarker.svg index be0c80bbb7..3cd5cf8d96 100644 --- a/resources/icons/legend_toolmarker.svg +++ b/resources/icons/legend_toolmarker.svg @@ -1,76 +1,3 @@ - - + + + From 78615546452dba0d5b25e9e9cef58871d36eb6e6 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 23 Nov 2021 10:59:52 +0100 Subject: [PATCH 25/27] New icons for legend toolbar --- resources/icons/legend_customgcodes.svg | 80 +++---------------------- resources/icons/legend_toolchanges.svg | 28 +++------ 2 files changed, 18 insertions(+), 90 deletions(-) diff --git a/resources/icons/legend_customgcodes.svg b/resources/icons/legend_customgcodes.svg index f363b39fdc..96e0be69e3 100644 --- a/resources/icons/legend_customgcodes.svg +++ b/resources/icons/legend_customgcodes.svg @@ -1,71 +1,9 @@ - - + + + + + + + + + diff --git a/resources/icons/legend_toolchanges.svg b/resources/icons/legend_toolchanges.svg index b6ed4c8a66..85b6218a9b 100644 --- a/resources/icons/legend_toolchanges.svg +++ b/resources/icons/legend_toolchanges.svg @@ -1,20 +1,10 @@ - - - - - - - - - - - - - + + + + + + + + + From 8bc442cd328ae41641d93a03244d4d2c84aac4d7 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 29 Nov 2021 11:46:28 +0100 Subject: [PATCH 26/27] Tech ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT - 2nd click on edit button exits editing state in slider --- resources/icons/edit_button_pressed.svg | 91 ++++++++++++++++++++ src/imgui/imconfig.h | 23 +++--- src/slic3r/GUI/ImGuiWrapper.cpp | 105 ++++++++++++++++++------ src/slic3r/GUI/ImGuiWrapper.hpp | 3 +- 4 files changed, 186 insertions(+), 36 deletions(-) create mode 100644 resources/icons/edit_button_pressed.svg diff --git a/resources/icons/edit_button_pressed.svg b/resources/icons/edit_button_pressed.svg new file mode 100644 index 0000000000..6e4058d10f --- /dev/null +++ b/resources/icons/edit_button_pressed.svg @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h index 27f5242a83..db0e54e60d 100644 --- a/src/imgui/imconfig.h +++ b/src/imgui/imconfig.h @@ -155,17 +155,18 @@ namespace ImGui const wchar_t ClippyMarker = 0x2602; const wchar_t InfoMarker = 0x2603; const wchar_t SliderFloatEditBtnIcon = 0x2604; - const wchar_t LegendTravel = 0x2605; - const wchar_t LegendWipe = 0x2606; - const wchar_t LegendRetract = 0x2607; - const wchar_t LegendDeretract = 0x2608; - const wchar_t LegendSeams = 0x2609; - const wchar_t LegendToolChanges = 0x2610; - const wchar_t LegendColorChanges = 0x2611; - const wchar_t LegendPausePrints = 0x2612; - const wchar_t LegendCustomGCodes = 0x2613; - const wchar_t LegendShells = 0x2614; - const wchar_t LegendToolMarker = 0x2615; + const wchar_t SliderFloatEditBtnPressedIcon = 0x2605; + const wchar_t LegendTravel = 0x2606; + const wchar_t LegendWipe = 0x2607; + const wchar_t LegendRetract = 0x2608; + const wchar_t LegendDeretract = 0x2609; + const wchar_t LegendSeams = 0x2610; + const wchar_t LegendToolChanges = 0x2611; + const wchar_t LegendColorChanges = 0x2612; + const wchar_t LegendPausePrints = 0x2613; + const wchar_t LegendCustomGCodes = 0x2614; + const wchar_t LegendShells = 0x2615; + const wchar_t LegendToolMarker = 0x2616; // void MyFunction(const char* name, const MyMatrix44& v); } diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index b4b37de839..00218af960 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -51,23 +51,24 @@ static const std::map font_icons = { {ImGui::MinimalizeHoverButton , "notification_minimalize_hover" }, {ImGui::RightArrowButton , "notification_right" }, {ImGui::RightArrowHoverButton , "notification_right_hover" }, - {ImGui::PreferencesButton , "notification_preferences" }, - {ImGui::PreferencesHoverButton , "notification_preferences_hover"}, + {ImGui::PreferencesButton , "notification_preferences" }, + {ImGui::PreferencesHoverButton, "notification_preferences_hover"}, #if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT - {ImGui::SliderFloatEditBtnIcon , "edit_button" }, + {ImGui::SliderFloatEditBtnIcon, "edit_button" }, + {ImGui::SliderFloatEditBtnPressedIcon, "edit_button_pressed" }, #endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT #if ENABLE_LEGEND_TOOLBAR_ICONS - {ImGui::LegendTravel , "legend_travel" }, - {ImGui::LegendWipe , "legend_wipe" }, - {ImGui::LegendRetract , "legend_retract" }, - {ImGui::LegendDeretract , "legend_deretract" }, - {ImGui::LegendSeams , "legend_seams" }, - {ImGui::LegendToolChanges , "legend_toolchanges" }, - {ImGui::LegendColorChanges , "legend_colorchanges" }, - {ImGui::LegendPausePrints , "legend_pauseprints" }, - {ImGui::LegendCustomGCodes , "legend_customgcodes" }, - {ImGui::LegendShells , "legend_shells" }, - {ImGui::LegendToolMarker , "legend_toolmarker" }, + {ImGui::LegendTravel , "legend_travel" }, + {ImGui::LegendWipe , "legend_wipe" }, + {ImGui::LegendRetract , "legend_retract" }, + {ImGui::LegendDeretract , "legend_deretract" }, + {ImGui::LegendSeams , "legend_seams" }, + {ImGui::LegendToolChanges , "legend_toolchanges" }, + {ImGui::LegendColorChanges , "legend_colorchanges" }, + {ImGui::LegendPausePrints , "legend_pauseprints" }, + {ImGui::LegendCustomGCodes , "legend_customgcodes" }, + {ImGui::LegendShells , "legend_shells" }, + {ImGui::LegendToolMarker , "legend_toolmarker" }, #endif // ENABLE_LEGEND_TOOLBAR_ICONS }; static const std::map font_icons_large = { @@ -423,11 +424,6 @@ bool ImGuiWrapper::draw_radio_button(const std::string& name, float size, bool a } #endif // ENABLE_PREVIEW_LAYOUT -bool ImGuiWrapper::image_button() -{ - return false; -} - bool ImGuiWrapper::input_double(const std::string &label, const double &value, const std::string &format) { return ImGui::InputDouble(label.c_str(), const_cast(&value), 0.0f, 0.0f, format.c_str(), ImGuiInputTextFlags_CharsDecimal); @@ -551,6 +547,9 @@ bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float ImGui::SameLine(); } + // the current slider edit state needs to be detected here before calling SliderFloat() + bool slider_editing = ImGui::GetCurrentWindow()->GetID(str_label.c_str()) == ImGui::GetActiveID(); + bool ret = ImGui::SliderFloat(str_label.c_str(), v, v_min, v_max, format, power); if (!tooltip.empty() && ImGui::IsItemHovered()) this->tooltip(into_u8(tooltip).c_str(), max_tooltip_width); @@ -562,15 +561,31 @@ bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float const ImGuiStyle& style = ImGui::GetStyle(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, { 1, style.ItemSpacing.y }); ImGui::SameLine(); - std::wstring btn_name = ImGui::SliderFloatEditBtnIcon + boost::nowide::widen(str_label); + ImGuiIO& io = ImGui::GetIO(); + assert(io.Fonts->TexWidth > 0 && io.Fonts->TexHeight > 0); + float inv_tex_w = 1.0f / float(io.Fonts->TexWidth); + float inv_tex_h = 1.0f / float(io.Fonts->TexHeight); + + const ImFontAtlasCustomRect* const rect = GetTextureCustomRect(slider_editing ? ImGui::SliderFloatEditBtnPressedIcon : ImGui::SliderFloatEditBtnIcon); + const ImVec2 size = { float(rect->Width), float(rect->Height) }; + const ImVec2 uv0 = ImVec2(float(rect->X) * inv_tex_w, float(rect->Y) * inv_tex_h); + const ImVec2 uv1 = ImVec2(float(rect->X + rect->Width) * inv_tex_w, float(rect->Y + rect->Height) * inv_tex_h); + ImGui::PushStyleColor(ImGuiCol_Button, { 0.25f, 0.25f, 0.25f, 0.0f }); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.5f, 0.5f, 0.5f, 1.0f }); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.5f, 0.5f, 0.5f, 1.0f }); - if (ImGui::Button(into_u8(btn_name).c_str())) { - ImGui::SetKeyboardFocusHere(-1); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.4f, 0.4f, 0.4f, 1.0f }); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.4f, 0.4f, 0.4f, 1.0f }); + + const ImTextureID tex_id = io.Fonts->TexID; + if (image_button(tex_id, size, uv0, uv1, -1, ImVec4(0.0, 0.0, 0.0, 0.0), ImVec4(1.0, 1.0, 1.0, 1.0), ImGuiButtonFlags_PressedOnClick)) { + if (!slider_editing) + ImGui::SetKeyboardFocusHere(-1); + else + ImGui::ClearActiveID(); this->set_requires_extra_frame(); } + ImGui::PopStyleColor(3); + if (ImGui::IsItemHovered()) this->tooltip(into_u8(_L("Edit")).c_str(), max_tooltip_width); @@ -590,6 +605,48 @@ bool ImGuiWrapper::slider_float(const wxString& label, float* v, float v_min, fl auto label_utf8 = into_u8(label); return this->slider_float(label_utf8.c_str(), v, v_min, v_max, format, power, clamp, tooltip, show_edit_btn); } + +static bool image_button_ex(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = ImGui::GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2); + ImGui::ItemSize(bb); + if (!ImGui::ItemAdd(bb, id)) + return false; + + bool hovered, held; + bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, flags); + + // Render + const ImU32 col = ImGui::GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + ImGui::RenderNavHighlight(bb, id); + ImGui::RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding)); + if (bg_col.w > 0.0f) + window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, ImGui::GetColorU32(bg_col)); + window->DrawList->AddImage(texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, ImGui::GetColorU32(tint_col)); + + return pressed; +} + +bool ImGuiWrapper::image_button(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + // Default to using texture ID as ID. User can still push string/integer prefixes. + ImGui::PushID((void*)(intptr_t)user_texture_id); + const ImGuiID id = window->GetID("#image"); + ImGui::PopID(); + + const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding; + return image_button_ex(id, user_texture_id, size, uv0, uv1, padding, bg_col, tint_col, flags); +} #else bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float v_max, const char* format/* = "%.3f"*/, float power/* = 1.0f*/, bool clamp /*= true*/) { diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index a4e25415c3..a1ecc6712f 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -86,7 +86,6 @@ public: #if ENABLE_PREVIEW_LAYOUT bool draw_radio_button(const std::string& name, float size, bool active, std::function draw_callback); #endif // ENABLE_PREVIEW_LAYOUT - bool image_button(); bool input_double(const std::string &label, const double &value, const std::string &format = "%.3f"); bool input_double(const wxString &label, const double &value, const std::string &format = "%.3f"); bool input_vec3(const std::string &label, const Vec3d &value, float width, const std::string &format = "%.3f"); @@ -109,6 +108,8 @@ public: bool slider_float(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true); bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true); bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true); + + bool image_button(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0.0, 0.0), const ImVec2& uv1 = ImVec2(1.0, 1.0), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0.0, 0.0, 0.0, 0.0), const ImVec4& tint_col = ImVec4(1.0, 1.0, 1.0, 1.0), ImGuiButtonFlags flags = 0); #else bool slider_float(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true); bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true); From 5218570348b2c733abb9842467b06eeae5be650a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 29 Nov 2021 12:46:27 +0100 Subject: [PATCH 27/27] Follow-up of 8bc442cd328ae41641d93a03244d4d2c84aac4d7 - Commented out unused code and fixed build when tech ENABLE_LEGEND_TOOLBAR_ICONS is disabled --- src/slic3r/GUI/GCodeViewer.cpp | 28 +++++++++++++++++++--------- src/slic3r/GUI/ImGuiWrapper.cpp | 11 +++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index baad791071..ea4b72cf17 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4380,16 +4380,16 @@ void GCodeViewer::render_legend(float& legend_height) } }; - auto circle_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) { - const float margin = 3.0f; - const ImVec2 center(0.5f * (pos.x + pos.x + size), 0.5f * (pos.y + pos.y + size)); - window.DrawList->AddCircleFilled(center, 0.5f * (size - 2.0f * margin), ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - }; - auto line_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) { - const float margin = 3.0f; - window.DrawList->AddLine({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin, pos.y + margin }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); - }; #if ENABLE_LEGEND_TOOLBAR_ICONS +// auto circle_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) { +// const float margin = 3.0f; +// const ImVec2 center(0.5f * (pos.x + pos.x + size), 0.5f * (pos.y + pos.y + size)); +// window.DrawList->AddCircleFilled(center, 0.5f * (size - 2.0f * margin), ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); +// }; +// auto line_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) { +// const float margin = 3.0f; +// window.DrawList->AddLine({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin, pos.y + margin }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); +// }; auto image_icon = [&imgui](ImGuiWindow& window, const ImVec2& pos, float size, const wchar_t& icon_id) { ImGuiIO& io = ImGui::GetIO(); const ImTextureID tex_id = io.Fonts->TexID; @@ -4400,6 +4400,16 @@ void GCodeViewer::render_legend(float& legend_height) const ImVec2 uv1 = { static_cast(rect->X + rect->Width) / tex_w, static_cast(rect->Y + rect->Height) / tex_h }; window.DrawList->AddImage(tex_id, pos, { pos.x + size, pos.y + size }, uv0, uv1, ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 1.0f })); }; +#else + auto circle_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) { + const float margin = 3.0f; + const ImVec2 center(0.5f * (pos.x + pos.x + size), 0.5f * (pos.y + pos.y + size)); + window.DrawList->AddCircleFilled(center, 0.5f * (size - 2.0f * margin), ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + }; + auto line_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) { + const float margin = 3.0f; + window.DrawList->AddLine({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin, pos.y + margin }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); + }; #endif // ENABLE_LEGEND_TOOLBAR_ICONS ImGui::Spacing(); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 7d7282511f..48186cde91 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -561,6 +561,8 @@ bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float if (show_edit_btn) { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, { 1, style.ItemSpacing.y }); ImGui::SameLine(); + +#if ENABLE_LEGEND_TOOLBAR_ICONS ImGuiIO& io = ImGui::GetIO(); assert(io.Fonts->TexWidth > 0 && io.Fonts->TexHeight > 0); float inv_tex_w = 1.0f / float(io.Fonts->TexWidth); @@ -570,11 +572,13 @@ bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float const ImVec2 size = { float(rect->Width), float(rect->Height) }; const ImVec2 uv0 = ImVec2(float(rect->X) * inv_tex_w, float(rect->Y) * inv_tex_h); const ImVec2 uv1 = ImVec2(float(rect->X + rect->Width) * inv_tex_w, float(rect->Y + rect->Height) * inv_tex_h); +#endif // ENABLE_LEGEND_TOOLBAR_ICONS ImGui::PushStyleColor(ImGuiCol_Button, { 0.25f, 0.25f, 0.25f, 0.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.4f, 0.4f, 0.4f, 1.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.4f, 0.4f, 0.4f, 1.0f }); +#if ENABLE_LEGEND_TOOLBAR_ICONS const ImTextureID tex_id = io.Fonts->TexID; if (image_button(tex_id, size, uv0, uv1, -1, ImVec4(0.0, 0.0, 0.0, 0.0), ImVec4(1.0, 1.0, 1.0, 1.0), ImGuiButtonFlags_PressedOnClick)) { if (!slider_editing) @@ -583,6 +587,13 @@ bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float ImGui::ClearActiveID(); this->set_requires_extra_frame(); } +#else + std::wstring btn_name = ImGui::SliderFloatEditBtnIcon + boost::nowide::widen(str_label); + if (ImGui::Button(into_u8(btn_name).c_str())) { + ImGui::SetKeyboardFocusHere(-1); + this->set_requires_extra_frame(); + } +#endif // ENABLE_LEGEND_TOOLBAR_ICONS ImGui::PopStyleColor(3);