mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 06:26:06 +08:00
Merge branch 'master' into fs_emboss
# Conflicts: # src/libslic3r/Technologies.hpp
This commit is contained in:
commit
28decf6f15
@ -9,6 +9,7 @@
|
|||||||
#include "GCode/WipeTower.hpp"
|
#include "GCode/WipeTower.hpp"
|
||||||
#include "ShortestPath.hpp"
|
#include "ShortestPath.hpp"
|
||||||
#include "Print.hpp"
|
#include "Print.hpp"
|
||||||
|
#include "Thread.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "ClipperUtils.hpp"
|
#include "ClipperUtils.hpp"
|
||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
@ -34,8 +35,6 @@
|
|||||||
#include "SVG.hpp"
|
#include "SVG.hpp"
|
||||||
|
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/task_scheduler_observer.h>
|
|
||||||
#include <tbb/enumerable_thread_specific.h>
|
|
||||||
|
|
||||||
// Intel redesigned some TBB interface considerably when merging TBB with their oneAPI set of libraries, see GH #7332.
|
// Intel redesigned some TBB interface considerably when merging TBB with their oneAPI set of libraries, see GH #7332.
|
||||||
// We are using quite an old TBB 2017 U7. Before we update our build servers, let's use the old API, which is deprecated in up to date TBB.
|
// We are using quite an old TBB 2017 U7. Before we update our build servers, let's use the old API, which is deprecated in up to date TBB.
|
||||||
@ -1469,32 +1468,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||||||
print.throw_if_canceled();
|
print.throw_if_canceled();
|
||||||
}
|
}
|
||||||
|
|
||||||
// For unknown reasons and in sporadic cases when GCode export is processing, some participating thread
|
|
||||||
// in tbb::parallel_pipeline has not set locales to "C", probably because this thread is newly spawned.
|
|
||||||
// So in this class method on_scheduler_entry is called for every thread before it starts participating
|
|
||||||
// in tbb::parallel_pipeline to ensure that locales are set correctly
|
|
||||||
|
|
||||||
// For tbb::parallel_pipeline, it seems that on_scheduler_entry is called for every layer and every filter.
|
|
||||||
// We ensure using thread-local storage that locales will be set to "C" just once for any participating thread.
|
|
||||||
class TBBLocalesSetter : public tbb::task_scheduler_observer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TBBLocalesSetter() { this->observe(true); }
|
|
||||||
~TBBLocalesSetter() override { this->observe(false); };
|
|
||||||
|
|
||||||
void on_scheduler_entry(bool is_worker) override
|
|
||||||
{
|
|
||||||
if (bool &is_locales_sets = m_is_locales_sets.local(); !is_locales_sets) {
|
|
||||||
// Set locales of the worker thread to "C".
|
|
||||||
set_c_locales();
|
|
||||||
is_locales_sets = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
tbb::enumerable_thread_specific<bool, tbb::cache_aligned_allocator<bool>, tbb::ets_key_usage_type::ets_key_per_instance> m_is_locales_sets{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Process all layers of all objects (non-sequential mode) with a parallel pipeline:
|
// Process all layers of all objects (non-sequential mode) with a parallel pipeline:
|
||||||
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
||||||
// and export G-code into file.
|
// and export G-code into file.
|
||||||
|
@ -43,8 +43,6 @@
|
|||||||
#define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_5_0_ALPHA1)
|
#define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
// Enable drawing the items in legend toolbar using icons
|
// Enable drawing the items in legend toolbar using icons
|
||||||
#define ENABLE_LEGEND_TOOLBAR_ICONS (1 && ENABLE_PREVIEW_LAYOUT)
|
#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_5_0_ALPHA1)
|
|
||||||
// Enable showing time estimate for travel moves in legend
|
// Enable showing time estimate for travel moves in legend
|
||||||
#define ENABLE_TRAVEL_TIME (1 && ENABLE_2_5_0_ALPHA1)
|
#define ENABLE_TRAVEL_TIME (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
// Enable removal of wipe tower magic object_id equal to 1000
|
// Enable removal of wipe tower magic object_id equal to 1000
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
#else
|
#else
|
||||||
// any posix system
|
// any posix system
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <pthread/qos.h>
|
||||||
|
#endif // __APPLE__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
@ -241,4 +244,26 @@ void name_tbb_thread_pool_threads_set_locale()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_current_thread_qos()
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// OSX specific: Set Quality of Service to "user initiated", so that the threads will be scheduled to high performance
|
||||||
|
// cores if available.
|
||||||
|
pthread_set_qos_class_self_np(QOS_CLASS_USER_INITIATED, 0);
|
||||||
|
#endif // __APPLE__
|
||||||
|
}
|
||||||
|
|
||||||
|
void TBBLocalesSetter::on_scheduler_entry(bool is_worker)
|
||||||
|
{
|
||||||
|
// static std::atomic<int> cnt = 0;
|
||||||
|
// std::cout << "TBBLocalesSetter Entering " << cnt ++ << " ID " << std::this_thread::get_id() << "\n";
|
||||||
|
if (bool& is_locales_sets = m_is_locales_sets.local(); !is_locales_sets) {
|
||||||
|
// Set locales of the worker thread to "C".
|
||||||
|
set_c_locales();
|
||||||
|
// OSX specific: Elevate QOS on Apple Silicon.
|
||||||
|
set_current_thread_qos();
|
||||||
|
is_locales_sets = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
#include <tbb/task_scheduler_observer.h>
|
||||||
|
#include <tbb/enumerable_thread_specific.h>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
// Set / get thread name.
|
// Set / get thread name.
|
||||||
@ -26,6 +29,10 @@ inline bool set_thread_name(boost::thread &thread, const std::string &thread_nam
|
|||||||
bool set_current_thread_name(const char *thread_name);
|
bool set_current_thread_name(const char *thread_name);
|
||||||
inline bool set_current_thread_name(const std::string &thread_name) { return set_current_thread_name(thread_name.c_str()); }
|
inline bool set_current_thread_name(const std::string &thread_name) { return set_current_thread_name(thread_name.c_str()); }
|
||||||
|
|
||||||
|
// OSX specific: Set Quality of Service to "user initiated", so that the threads will be scheduled to high performance
|
||||||
|
// cores if available.
|
||||||
|
void set_current_thread_qos();
|
||||||
|
|
||||||
// Returns nullopt if not supported.
|
// Returns nullopt if not supported.
|
||||||
// Not supported by OSX.
|
// Not supported by OSX.
|
||||||
// Naming threads is only supported on newer Windows 10.
|
// Naming threads is only supported on newer Windows 10.
|
||||||
@ -53,6 +60,25 @@ template<class Fn> inline boost::thread create_thread(Fn &&fn)
|
|||||||
return create_thread(attrs, std::forward<Fn>(fn));
|
return create_thread(attrs, std::forward<Fn>(fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For unknown reasons and in sporadic cases when GCode export is processing, some participating thread
|
||||||
|
// in tbb::parallel_pipeline has not set locales to "C", probably because this thread is newly spawned.
|
||||||
|
// So in this class method on_scheduler_entry is called for every thread before it starts participating
|
||||||
|
// in tbb::parallel_pipeline to ensure that locales are set correctly
|
||||||
|
//
|
||||||
|
// For tbb::parallel_pipeline, it seems that on_scheduler_entry is called for every layer and every filter.
|
||||||
|
// We ensure using thread-local storage that locales will be set to "C" just once for any participating thread.
|
||||||
|
class TBBLocalesSetter : public tbb::task_scheduler_observer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TBBLocalesSetter() { this->observe(true); }
|
||||||
|
~TBBLocalesSetter() override { this->observe(false); };
|
||||||
|
|
||||||
|
void on_scheduler_entry(bool is_worker) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tbb::enumerable_thread_specific<bool, tbb::cache_aligned_allocator<bool>, tbb::ets_key_usage_type::ets_key_per_instance> m_is_locales_sets{ false };
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GUI_THREAD_HPP
|
#endif // GUI_THREAD_HPP
|
||||||
|
@ -211,6 +211,12 @@ void BackgroundSlicingProcess::thread_proc()
|
|||||||
set_current_thread_name("slic3r_BgSlcPcs");
|
set_current_thread_name("slic3r_BgSlcPcs");
|
||||||
name_tbb_thread_pool_threads_set_locale();
|
name_tbb_thread_pool_threads_set_locale();
|
||||||
|
|
||||||
|
// Set "C" locales and enforce OSX QoS level on all threads entering an arena.
|
||||||
|
// The cost of the callback is quite low: The callback is called once per thread
|
||||||
|
// entering a parallel loop and the callback is guarded with a thread local
|
||||||
|
// variable to be executed just once.
|
||||||
|
TBBLocalesSetter setter;
|
||||||
|
|
||||||
assert(m_print != nullptr);
|
assert(m_print != nullptr);
|
||||||
assert(m_print == m_fff_print || m_print == m_sla_print);
|
assert(m_print == m_fff_print || m_print == m_sla_print);
|
||||||
std::unique_lock<std::mutex> lck(m_mutex);
|
std::unique_lock<std::mutex> lck(m_mutex);
|
||||||
|
@ -250,7 +250,6 @@ void GCodeViewer::COG::render()
|
|||||||
//ImGui::PopStyleVar();
|
//ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
float GCodeViewer::Extrusions::Range::step_size(EType type) const
|
float GCodeViewer::Extrusions::Range::step_size(EType type) const
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
@ -262,12 +261,8 @@ float GCodeViewer::Extrusions::Range::step_size(EType type) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
ColorRGBA GCodeViewer::Extrusions::Range::get_color_at(float value, EType type) const
|
ColorRGBA GCodeViewer::Extrusions::Range::get_color_at(float value, EType type) const
|
||||||
#else
|
|
||||||
ColorRGBA GCodeViewer::Extrusions::Range::get_color_at(float value) const
|
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
{
|
{
|
||||||
// Input value scaled to the colors range
|
// Input value scaled to the colors range
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
float global_t = 0.0f;
|
float global_t = 0.0f;
|
||||||
const float step = step_size(type);
|
const float step = step_size(type);
|
||||||
if (step > 0.0f) {
|
if (step > 0.0f) {
|
||||||
@ -278,10 +273,6 @@ ColorRGBA GCodeViewer::Extrusions::Range::get_color_at(float value) const
|
|||||||
case EType::Logarithmic: { global_t = (value > min && min > 0.0f) ? ::log(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;
|
const size_t color_max_idx = Range_Colors.size() - 1;
|
||||||
|
|
||||||
@ -901,7 +892,6 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
for (size_t i = 0; i < gcode_result.print_statistics.modes.size(); ++i) {
|
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;
|
m_layers_times[i] = gcode_result.print_statistics.modes[i].layers_times;
|
||||||
}
|
}
|
||||||
@ -911,7 +901,6 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v
|
|||||||
m_extrusions.ranges.layer_time[i].update_from(time);
|
m_extrusions.ranges.layer_time[i].update_from(time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
m_statistics.refresh_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start_time).count();
|
m_statistics.refresh_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start_time).count();
|
||||||
@ -960,11 +949,9 @@ void GCodeViewer::reset()
|
|||||||
m_layers_z_range = { 0, 0 };
|
m_layers_z_range = { 0, 0 };
|
||||||
m_roles = std::vector<ExtrusionRole>();
|
m_roles = std::vector<ExtrusionRole>();
|
||||||
m_print_statistics.reset();
|
m_print_statistics.reset();
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||||
m_layers_times[i] = std::vector<float>();
|
m_layers_times[i] = std::vector<float>();
|
||||||
}
|
}
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
m_custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
|
m_custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
|
||||||
m_sequential_view.gcode_window.reset();
|
m_sequential_view.gcode_window.reset();
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
@ -2435,7 +2422,6 @@ 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::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::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; }
|
case EViewType::Temperature: { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; }
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
case EViewType::LayerTimeLinear:
|
case EViewType::LayerTimeLinear:
|
||||||
case EViewType::LayerTimeLogarithmic: {
|
case EViewType::LayerTimeLogarithmic: {
|
||||||
const Path::Sub_Path& sub_path = path.sub_paths.front();
|
const Path::Sub_Path& sub_path = path.sub_paths.front();
|
||||||
@ -2454,7 +2440,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
}
|
}
|
||||||
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::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::Tool: { color = m_tool_colors[path.extruder_id]; break; }
|
||||||
case EViewType::ColorPrint: {
|
case EViewType::ColorPrint: {
|
||||||
@ -3464,14 +3449,9 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
};
|
};
|
||||||
|
|
||||||
const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast<size_t>(m_time_estimate_mode)];
|
const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast<size_t>(m_time_estimate_mode)];
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType ||
|
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::LayerTimeLinear || m_view_type == EViewType::LayerTimeLogarithmic ||
|
||||||
(m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty()));
|
(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 icon_size = ImGui::GetTextLineHeight();
|
||||||
const float percent_bar_size = 2.0f * ImGui::GetTextLineHeight();
|
const float percent_bar_size = 2.0f * ImGui::GetTextLineHeight();
|
||||||
@ -3613,7 +3593,6 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
auto append_time_range = [append_item](const Extrusions::Range& range, Extrusions::Range::EType type) {
|
auto append_time_range = [append_item](const Extrusions::Range& range, Extrusions::Range::EType type) {
|
||||||
auto append_range_item = [append_item](int i, float value) {
|
auto append_range_item = [append_item](int i, float value) {
|
||||||
std::string str_value = get_time_dhms(value);
|
std::string str_value = get_time_dhms(value);
|
||||||
@ -3644,7 +3623,6 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
|
|
||||||
auto append_headers = [&imgui](const std::array<std::string, 5>& texts, const std::array<float, 4>& offsets) {
|
auto append_headers = [&imgui](const std::array<std::string, 5>& texts, const std::array<float, 4>& offsets) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -3836,10 +3814,8 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
_u8L("Fan speed (%)"),
|
_u8L("Fan speed (%)"),
|
||||||
_u8L("Temperature (°C)"),
|
_u8L("Temperature (°C)"),
|
||||||
_u8L("Volumetric flow rate (mm³/s)"),
|
_u8L("Volumetric flow rate (mm³/s)"),
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
_u8L("Layer time (linear)"),
|
_u8L("Layer time (linear)"),
|
||||||
_u8L("Layer time (logarithmic)"),
|
_u8L("Layer time (logarithmic)"),
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
_u8L("Tool"),
|
_u8L("Tool"),
|
||||||
_u8L("Color Print") }, view_type, ImGuiComboFlags_HeightLargest);
|
_u8L("Color Print") }, view_type, ImGuiComboFlags_HeightLargest);
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
@ -3873,10 +3849,8 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; }
|
case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; }
|
||||||
case EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; }
|
case EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; }
|
||||||
case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; }
|
case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; }
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
case EViewType::LayerTimeLinear: { imgui.title(_u8L("Layer time (linear)")); break; }
|
case EViewType::LayerTimeLinear: { imgui.title(_u8L("Layer time (linear)")); break; }
|
||||||
case EViewType::LayerTimeLogarithmic: { imgui.title(_u8L("Layer time (logarithmic)")); 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);
|
append_headers({ _u8L("Tool"), _u8L("Used filament") }, offsets);
|
||||||
break;
|
break;
|
||||||
@ -3931,10 +3905,8 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
case EViewType::FanSpeed: { append_range(m_extrusions.ranges.fan_speed, 0); 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::Temperature: { append_range(m_extrusions.ranges.temperature, 0); break; }
|
||||||
case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; }
|
case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; }
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
case EViewType::LayerTimeLinear: { append_time_range(m_extrusions.ranges.layer_time[static_cast<size_t>(m_time_estimate_mode)], Extrusions::Range::EType::Linear); break; }
|
case EViewType::LayerTimeLinear: { append_time_range(m_extrusions.ranges.layer_time[static_cast<size_t>(m_time_estimate_mode)], Extrusions::Range::EType::Linear); break; }
|
||||||
case EViewType::LayerTimeLogarithmic: { append_time_range(m_extrusions.ranges.layer_time[static_cast<size_t>(m_time_estimate_mode)], Extrusions::Range::EType::Logarithmic); break; }
|
case EViewType::LayerTimeLogarithmic: { append_time_range(m_extrusions.ranges.layer_time[static_cast<size_t>(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
|
// shows only extruders actually used
|
||||||
for (unsigned char extruder_id : m_extruder_ids) {
|
for (unsigned char extruder_id : m_extruder_ids) {
|
||||||
@ -4275,6 +4247,14 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
}
|
}
|
||||||
#endif // !ENABLE_PREVIEW_LAYOUT
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
|
auto add_strings_row_to_table = [&imgui](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
imgui.text_colored(col_1_color, col_1.c_str());
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
imgui.text_colored(col_2_color, col_2.c_str());
|
||||||
|
};
|
||||||
|
|
||||||
// settings section
|
// settings section
|
||||||
bool has_settings = false;
|
bool has_settings = false;
|
||||||
has_settings |= !m_settings_ids.print.empty();
|
has_settings |= !m_settings_ids.print.empty();
|
||||||
@ -4289,47 +4269,37 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
show_settings &= (m_view_type == EViewType::FeatureType || m_view_type == EViewType::Tool);
|
show_settings &= (m_view_type == EViewType::FeatureType || m_view_type == EViewType::Tool);
|
||||||
show_settings &= has_settings;
|
show_settings &= has_settings;
|
||||||
if (show_settings) {
|
if (show_settings) {
|
||||||
auto calc_offset = [this]() {
|
|
||||||
float ret = 0.0f;
|
|
||||||
if (!m_settings_ids.printer.empty())
|
|
||||||
ret = std::max(ret, ImGui::CalcTextSize((_u8L("Printer") + std::string(":")).c_str()).x);
|
|
||||||
if (!m_settings_ids.print.empty())
|
|
||||||
ret = std::max(ret, ImGui::CalcTextSize((_u8L("Print settings") + std::string(":")).c_str()).x);
|
|
||||||
if (!m_settings_ids.filament.empty()) {
|
|
||||||
for (unsigned char i : m_extruder_ids) {
|
|
||||||
ret = std::max(ret, ImGui::CalcTextSize((_u8L("Filament") + " " + std::to_string(i + 1) + ":").c_str()).x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ret > 0.0f)
|
|
||||||
ret += 2.0f * ImGui::GetStyle().ItemSpacing.x;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
imgui.title(_u8L("Settings"));
|
imgui.title(_u8L("Settings"));
|
||||||
|
|
||||||
float offset = calc_offset();
|
auto trim_text_if_needed = [](const std::string& txt) {
|
||||||
|
const float max_length = 250.0f;
|
||||||
|
const float length = ImGui::CalcTextSize(txt.c_str()).x;
|
||||||
|
if (length > max_length) {
|
||||||
|
const size_t new_len = txt.length() * max_length / length;
|
||||||
|
return txt.substr(0, new_len) + "...";
|
||||||
|
}
|
||||||
|
return txt;
|
||||||
|
};
|
||||||
|
|
||||||
if (!m_settings_ids.printer.empty()) {
|
if (ImGui::BeginTable("Settings", 2)) {
|
||||||
imgui.text(_u8L("Printer") + ":");
|
if (!m_settings_ids.printer.empty())
|
||||||
ImGui::SameLine(offset);
|
add_strings_row_to_table(_u8L("Printer") + ":", ImGuiWrapper::COL_ORANGE_LIGHT,
|
||||||
imgui.text(m_settings_ids.printer);
|
trim_text_if_needed(m_settings_ids.printer), ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()));
|
||||||
}
|
if (!m_settings_ids.print.empty())
|
||||||
if (!m_settings_ids.print.empty()) {
|
add_strings_row_to_table(_u8L("Print settings") + ":", ImGuiWrapper::COL_ORANGE_LIGHT,
|
||||||
imgui.text(_u8L("Print settings") + ":");
|
trim_text_if_needed(m_settings_ids.print), ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()));
|
||||||
ImGui::SameLine(offset);
|
if (!m_settings_ids.filament.empty()) {
|
||||||
imgui.text(m_settings_ids.print);
|
for (unsigned char i : m_extruder_ids) {
|
||||||
}
|
if (i < static_cast<unsigned char>(m_settings_ids.filament.size()) && !m_settings_ids.filament[i].empty()) {
|
||||||
if (!m_settings_ids.filament.empty()) {
|
std::string txt = _u8L("Filament");
|
||||||
for (unsigned char i : m_extruder_ids) {
|
txt += (m_extruder_ids.size() == 1) ? ":" : " " + std::to_string(i + 1);
|
||||||
if (i < static_cast<unsigned char>(m_settings_ids.filament.size()) && !m_settings_ids.filament[i].empty()) {
|
add_strings_row_to_table(txt, ImGuiWrapper::COL_ORANGE_LIGHT,
|
||||||
std::string txt = _u8L("Filament");
|
trim_text_if_needed(m_settings_ids.filament[i]), ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()));
|
||||||
txt += (m_extruder_ids.size() == 1) ? ":" : " " + std::to_string(i + 1);
|
}
|
||||||
imgui.text(txt);
|
|
||||||
ImGui::SameLine(offset);
|
|
||||||
imgui.text(m_settings_ids.filament[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4363,33 +4333,24 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
|
|
||||||
imgui.title(time_title + ":");
|
imgui.title(time_title + ":");
|
||||||
|
|
||||||
std::string first_str = _u8L("First layer");
|
if (ImGui::BeginTable("Times", 2)) {
|
||||||
std::string total_str = _u8L("Total");
|
if (!time_mode.layers_times.empty()) {
|
||||||
|
add_strings_row_to_table(_u8L("First layer") + ":", ImGuiWrapper::COL_ORANGE_LIGHT,
|
||||||
|
short_time(get_time_dhms(time_mode.layers_times.front())), ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()));
|
||||||
|
}
|
||||||
|
|
||||||
float max_len = 10.0f + ImGui::GetStyle().ItemSpacing.x;
|
add_strings_row_to_table(_u8L("Total") + ":", ImGuiWrapper::COL_ORANGE_LIGHT,
|
||||||
if (time_mode.layers_times.empty())
|
short_time(get_time_dhms(time_mode.time)), ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()));
|
||||||
max_len += ImGui::CalcTextSize(total_str.c_str()).x;
|
|
||||||
else
|
|
||||||
max_len += std::max(ImGui::CalcTextSize(first_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x);
|
|
||||||
|
|
||||||
if (!time_mode.layers_times.empty()) {
|
ImGui::EndTable();
|
||||||
imgui.text(first_str + ":");
|
|
||||||
ImGui::SameLine(max_len);
|
|
||||||
imgui.text(short_time(get_time_dhms(time_mode.layers_times.front())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imgui.text(total_str + ":");
|
|
||||||
ImGui::SameLine(max_len);
|
|
||||||
imgui.text(short_time(get_time_dhms(time_mode.time)));
|
|
||||||
|
|
||||||
auto show_mode_button = [this, &imgui, can_show_mode_button](const wxString& label, PrintEstimatedStatistics::ETimeMode mode) {
|
auto show_mode_button = [this, &imgui, can_show_mode_button](const wxString& label, PrintEstimatedStatistics::ETimeMode mode) {
|
||||||
if (can_show_mode_button(mode)) {
|
if (can_show_mode_button(mode)) {
|
||||||
if (imgui.button(label)) {
|
if (imgui.button(label)) {
|
||||||
m_time_estimate_mode = mode;
|
m_time_estimate_mode = mode;
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
if (m_view_type == EViewType::LayerTimeLinear || m_view_type == EViewType::LayerTimeLogarithmic)
|
if (m_view_type == EViewType::LayerTimeLinear || m_view_type == EViewType::LayerTimeLogarithmic)
|
||||||
refresh_render_paths(false, false);
|
refresh_render_paths(false, false);
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
imgui.set_requires_extra_frame();
|
imgui.set_requires_extra_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -432,13 +432,11 @@ class GCodeViewer
|
|||||||
{
|
{
|
||||||
struct Range
|
struct Range
|
||||||
{
|
{
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
enum class EType : unsigned char
|
enum class EType : unsigned char
|
||||||
{
|
{
|
||||||
Linear,
|
Linear,
|
||||||
Logarithmic
|
Logarithmic
|
||||||
};
|
};
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
|
|
||||||
float min;
|
float min;
|
||||||
float max;
|
float max;
|
||||||
@ -454,13 +452,8 @@ class GCodeViewer
|
|||||||
}
|
}
|
||||||
void reset() { min = FLT_MAX; max = -FLT_MAX; count = 0; }
|
void reset() { min = FLT_MAX; max = -FLT_MAX; count = 0; }
|
||||||
|
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
float step_size(EType type = EType::Linear) const;
|
float step_size(EType type = EType::Linear) const;
|
||||||
ColorRGBA get_color_at(float value, EType type = EType::Linear) const;
|
ColorRGBA get_color_at(float value, EType type = EType::Linear) const;
|
||||||
#else
|
|
||||||
float step_size() const { return (max - min) / (static_cast<float>(Range_Colors.size()) - 1.0f); }
|
|
||||||
ColorRGBA get_color_at(float value) const;
|
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ranges
|
struct Ranges
|
||||||
@ -477,10 +470,8 @@ class GCodeViewer
|
|||||||
Range volumetric_rate;
|
Range volumetric_rate;
|
||||||
// Color mapping by extrusion temperature.
|
// Color mapping by extrusion temperature.
|
||||||
Range temperature;
|
Range temperature;
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
// Color mapping by layer time.
|
// Color mapping by layer time.
|
||||||
std::array<Range, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> layer_time;
|
std::array<Range, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> layer_time;
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
height.reset();
|
height.reset();
|
||||||
@ -489,11 +480,9 @@ class GCodeViewer
|
|||||||
fan_speed.reset();
|
fan_speed.reset();
|
||||||
volumetric_rate.reset();
|
volumetric_rate.reset();
|
||||||
temperature.reset();
|
temperature.reset();
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
for (auto& range : layer_time) {
|
for (auto& range : layer_time) {
|
||||||
range.reset();
|
range.reset();
|
||||||
}
|
}
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -752,10 +741,8 @@ public:
|
|||||||
FanSpeed,
|
FanSpeed,
|
||||||
Temperature,
|
Temperature,
|
||||||
VolumetricRate,
|
VolumetricRate,
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
LayerTimeLinear,
|
LayerTimeLinear,
|
||||||
LayerTimeLogarithmic,
|
LayerTimeLogarithmic,
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
Tool,
|
Tool,
|
||||||
ColorPrint,
|
ColorPrint,
|
||||||
Count
|
Count
|
||||||
@ -801,9 +788,7 @@ private:
|
|||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
GCodeProcessorResult::SettingsIds m_settings_ids;
|
GCodeProcessorResult::SettingsIds m_settings_ids;
|
||||||
std::array<SequentialRangeCap, 2> m_sequential_range_caps;
|
std::array<SequentialRangeCap, 2> m_sequential_range_caps;
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
std::array<std::vector<float>, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> m_layers_times;
|
std::array<std::vector<float>, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> m_layers_times;
|
||||||
#endif // ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
|
|
||||||
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
|
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
|
||||||
|
|
||||||
|
@ -222,10 +222,8 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||||||
m_choice_view_type->Append(_L("Fan speed"));
|
m_choice_view_type->Append(_L("Fan speed"));
|
||||||
m_choice_view_type->Append(_L("Temperature"));
|
m_choice_view_type->Append(_L("Temperature"));
|
||||||
m_choice_view_type->Append(_L("Volumetric flow rate"));
|
m_choice_view_type->Append(_L("Volumetric flow rate"));
|
||||||
#if ENABLE_PREVIEW_LAYER_TIME
|
|
||||||
m_choice_view_type->Append(_L("Layer time (linear)"));
|
m_choice_view_type->Append(_L("Layer time (linear)"));
|
||||||
m_choice_view_type->Append(_L("Layer time (logarithmic)"));
|
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("Tool"));
|
||||||
m_choice_view_type->Append(_L("Color Print"));
|
m_choice_view_type->Append(_L("Color Print"));
|
||||||
m_choice_view_type->SetSelection(0);
|
m_choice_view_type->SetSelection(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user