From 1532920d81411f07ecb80edf6dbb6396fce73fab Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 3 Aug 2020 08:46:32 +0200 Subject: [PATCH] GCodeProcessor -> Extended import of config data from gcode saved by PrusaSlicer --- src/libslic3r/GCode/GCodeProcessor.cpp | 207 ++++++++++++++++++++++--- src/libslic3r/GCode/GCodeProcessor.hpp | 8 +- src/slic3r/GUI/GCodeViewer.cpp | 17 +- src/slic3r/GUI/KBShortcutsDialog.cpp | 6 + 4 files changed, 205 insertions(+), 33 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index c10552482..f3e07da88 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -24,9 +24,9 @@ namespace Slic3r { const std::string GCodeProcessor::Extrusion_Role_Tag = "ExtrType:"; const std::string GCodeProcessor::Width_Tag = "PrusaSlicer__WIDTH:"; const std::string GCodeProcessor::Height_Tag = "Height:"; -const std::string GCodeProcessor::Color_Change_Tag = "COLOR_CHANGE"; -const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE_PRINT"; -const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM_CODE"; +const std::string GCodeProcessor::Color_Change_Tag = "Color change"; +const std::string GCodeProcessor::Pause_Print_Tag = "Pause print"; +const std::string GCodeProcessor::Custom_Code_Tag = "Custom gcode"; static bool is_valid_extrusion_role(int value) { @@ -297,7 +297,7 @@ void GCodeProcessor::TimeProcessor::reset() const std::vector> GCodeProcessor::Producers = { { EProducer::PrusaSlicer, "PrusaSlicer" }, - { EProducer::Cura, "Cura" }, + { EProducer::Cura, "Cura_SteamEngine" }, { EProducer::Simplify3D, "Simplify3D" }, { EProducer::CraftWare, "CraftWare" }, { EProducer::ideaMaker, "ideaMaker" } @@ -314,32 +314,34 @@ void GCodeProcessor::apply_config(const PrintConfig& config) size_t extruders_count = config.nozzle_diameter.values.size(); m_extruder_offsets.resize(extruders_count); - for (size_t id = 0; id < extruders_count; ++id) { - Vec2f offset = config.extruder_offset.get_at(id).cast(); - m_extruder_offsets[id] = Vec3f(offset(0), offset(1), 0.0f); + for (size_t i = 0; i < extruders_count; ++i) { + Vec2f offset = config.extruder_offset.get_at(i).cast(); + m_extruder_offsets[i] = { offset(0), offset(1), 0.0f }; } - m_extruders_color.resize(extruders_count); - for (size_t id = 0; id < extruders_count; ++id) { - m_extruders_color[id] = static_cast(id); + m_extruder_colors.resize(extruders_count); + for (size_t i = 0; i < extruders_count; ++i) { + m_extruder_colors[i] = static_cast(i); } - for (double diam : config.filament_diameter.values) { - m_filament_diameters.push_back(static_cast(diam)); + m_filament_diameters.resize(config.filament_diameter.values.size()); + for (size_t i = 0; i < config.filament_diameter.values.size(); ++i) { + m_filament_diameters[i] = static_cast(config.filament_diameter.values[i]); } m_time_processor.machine_limits = reinterpret_cast(config); // Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful. // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they // are considered to be active for the single extruder multi-material printers only. - m_time_processor.filament_load_times.clear(); - for (double d : config.filament_load_time.values) { - m_time_processor.filament_load_times.push_back(static_cast(d)); + m_time_processor.filament_load_times.resize(config.filament_load_time.values.size()); + for (size_t i = 0; i < config.filament_load_time.values.size(); ++i) { + m_time_processor.filament_load_times[i] = static_cast(config.filament_load_time.values[i]); } - m_time_processor.filament_unload_times.clear(); - for (double d : config.filament_unload_time.values) { - m_time_processor.filament_unload_times.push_back(static_cast(d)); + m_time_processor.filament_unload_times.resize(config.filament_unload_time.values.size()); + for (size_t i = 0; i < config.filament_unload_time.values.size(); ++i) { + m_time_processor.filament_unload_times[i] = static_cast(config.filament_unload_time.values[i]); } + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; @@ -350,6 +352,14 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) { m_parser.apply_config(config); + const ConfigOptionEnum* gcode_flavor = config.option>("gcode_flavor"); + if (gcode_flavor != nullptr) + m_flavor = gcode_flavor->value; + + const ConfigOptionPoints* bed_shape = config.option("bed_shape"); + if (bed_shape != nullptr) + m_result.bed_shape = bed_shape->values; + const ConfigOptionFloats* filament_diameters = config.option("filament_diameter"); if (filament_diameters != nullptr) { for (double diam : filament_diameters->values) { @@ -357,9 +367,127 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) } } - const ConfigOptionPoints* bed_shape = config.option("bed_shape"); - if (bed_shape != nullptr) - m_result.bed_shape = bed_shape->values; + const ConfigOptionPoints* extruder_offset = config.option("extruder_offset"); + if (extruder_offset != nullptr) { + m_extruder_offsets.resize(extruder_offset->values.size()); + for (size_t i = 0; i < extruder_offset->values.size(); ++i) { + Vec2f offset = extruder_offset->values[i].cast(); + m_extruder_offsets[i] = { offset(0), offset(1), 0.0f }; + } + } + + // ensure at least one (default) color is defined + std::string default_color = "#FF8000"; + m_result.extruder_colors = std::vector(1, default_color); + const ConfigOptionStrings* extruder_colour = config.option("extruder_colour"); + if (extruder_colour != nullptr) { + // takes colors from config + m_result.extruder_colors = extruder_colour->values; + // try to replace missing values with filament colors + const ConfigOptionStrings* filament_colour = config.option("filament_colour"); + if (filament_colour != nullptr && filament_colour->values.size() == m_result.extruder_colors.size()) { + for (size_t i = 0; i < m_result.extruder_colors.size(); ++i) { + if (m_result.extruder_colors[i].empty()) + m_result.extruder_colors[i] = filament_colour->values[i]; + } + } + } + + // replace missing values with default + for (size_t i = 0; i < m_result.extruder_colors.size(); ++i) { + if (m_result.extruder_colors[i].empty()) + m_result.extruder_colors[i] = default_color; + } + + m_extruder_colors.resize(m_result.extruder_colors.size()); + for (size_t i = 0; i < m_result.extruder_colors.size(); ++i) { + m_extruder_colors[i] = static_cast(i); + } + + const ConfigOptionFloats* filament_load_time = config.option("filament_load_time"); + if (filament_load_time != nullptr) { + m_time_processor.filament_load_times.resize(filament_load_time->values.size()); + for (size_t i = 0; i < filament_load_time->values.size(); ++i) { + m_time_processor.filament_load_times[i] = static_cast(filament_load_time->values[i]); + } + } + + const ConfigOptionFloats* filament_unload_time = config.option("filament_unload_time"); + if (filament_unload_time != nullptr) { + m_time_processor.filament_unload_times.resize(filament_unload_time->values.size()); + for (size_t i = 0; i < filament_unload_time->values.size(); ++i) { + m_time_processor.filament_unload_times[i] = static_cast(filament_unload_time->values[i]); + } + } + + const ConfigOptionFloats* machine_max_acceleration_x = config.option("machine_max_acceleration_x"); + if (machine_max_acceleration_x != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_x.values = machine_max_acceleration_x->values; + + const ConfigOptionFloats* machine_max_acceleration_y = config.option("machine_max_acceleration_y"); + if (machine_max_acceleration_y != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_y.values = machine_max_acceleration_y->values; + + const ConfigOptionFloats* machine_max_acceleration_z = config.option("machine_max_acceleration_z"); + if (machine_max_acceleration_z != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_z.values = machine_max_acceleration_z->values; + + const ConfigOptionFloats* machine_max_acceleration_e = config.option("machine_max_acceleration_e"); + if (machine_max_acceleration_e != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_e.values = machine_max_acceleration_e->values; + + const ConfigOptionFloats* machine_max_feedrate_x = config.option("machine_max_feedrate_x"); + if (machine_max_feedrate_x != nullptr) + m_time_processor.machine_limits.machine_max_feedrate_x.values = machine_max_feedrate_x->values; + + const ConfigOptionFloats* machine_max_feedrate_y = config.option("machine_max_feedrate_y"); + if (machine_max_feedrate_y != nullptr) + m_time_processor.machine_limits.machine_max_feedrate_y.values = machine_max_feedrate_y->values; + + const ConfigOptionFloats* machine_max_feedrate_z = config.option("machine_max_feedrate_z"); + if (machine_max_feedrate_z != nullptr) + m_time_processor.machine_limits.machine_max_feedrate_z.values = machine_max_feedrate_z->values; + + const ConfigOptionFloats* machine_max_feedrate_e = config.option("machine_max_feedrate_e"); + if (machine_max_feedrate_e != nullptr) + m_time_processor.machine_limits.machine_max_feedrate_e.values = machine_max_feedrate_e->values; + + const ConfigOptionFloats* machine_max_jerk_x = config.option("machine_max_jerk_x"); + if (machine_max_jerk_x != nullptr) + m_time_processor.machine_limits.machine_max_jerk_x.values = machine_max_jerk_x->values; + + const ConfigOptionFloats* machine_max_jerk_y = config.option("machine_max_jerk_y"); + if (machine_max_jerk_y != nullptr) + m_time_processor.machine_limits.machine_max_jerk_y.values = machine_max_jerk_y->values; + + const ConfigOptionFloats* machine_max_jerk_z = config.option("machine_max_jerkz"); + if (machine_max_jerk_z != nullptr) + m_time_processor.machine_limits.machine_max_jerk_z.values = machine_max_jerk_z->values; + + const ConfigOptionFloats* machine_max_jerk_e = config.option("machine_max_jerk_e"); + if (machine_max_jerk_e != nullptr) + m_time_processor.machine_limits.machine_max_jerk_e.values = machine_max_jerk_e->values; + + const ConfigOptionFloats* machine_max_acceleration_extruding = config.option("machine_max_acceleration_extruding"); + if (machine_max_acceleration_extruding != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_extruding.values = machine_max_acceleration_extruding->values; + + const ConfigOptionFloats* machine_max_acceleration_retracting = config.option("machine_max_acceleration_retracting"); + if (machine_max_acceleration_retracting != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_retracting.values = machine_max_acceleration_retracting->values; + + const ConfigOptionFloats* machine_min_extruding_rate = config.option("machine_min_extruding_rate"); + if (machine_min_extruding_rate != nullptr) + m_time_processor.machine_limits.machine_min_extruding_rate.values = machine_min_extruding_rate->values; + + const ConfigOptionFloats* machine_min_travel_rate = config.option("machine_min_travel_rate"); + if (machine_min_travel_rate != nullptr) + m_time_processor.machine_limits.machine_min_travel_rate.values = machine_min_travel_rate->values; + + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); + m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; + } } void GCodeProcessor::enable_stealth_time_estimator(bool enabled) @@ -388,7 +516,7 @@ void GCodeProcessor::reset() m_extrusion_role = erNone; m_extruder_id = 0; - m_extruders_color = ExtrudersColor(); + m_extruder_colors = ExtruderColors(); m_filament_diameters = std::vector(); m_cp_color.reset(); @@ -643,13 +771,13 @@ void GCodeProcessor::process_tags(const std::string& comment) { unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast(std::stoi(comment.substr(pos + 1))); - m_extruders_color[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview + m_extruder_colors[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview ++m_cp_color.counter; if (m_cp_color.counter == UCHAR_MAX) m_cp_color.counter = 0; if (m_extruder_id == extruder_id) { - m_cp_color.current = m_extruders_color[extruder_id]; + m_cp_color.current = m_extruder_colors[extruder_id]; store_move_vertex(EMoveType::Color_change); } @@ -728,6 +856,35 @@ bool GCodeProcessor::process_cura_tags(const std::string& comment) return true; } + // flavor + tag = "FLAVOR:"; + pos = comment.find(tag); + if (pos != comment.npos) { + std::string flavor = comment.substr(pos + tag.length()); + if (flavor == "BFB") + m_flavor = gcfMarlin; // << ??????????????????????? + else if (flavor == "Mach3") + m_flavor = gcfMach3; + else if (flavor == "Makerbot") + m_flavor = gcfMakerWare; + else if (flavor == "UltiGCode") + m_flavor = gcfMarlin; // << ??????????????????????? + else if (flavor == "Marlin(Volumetric)") + m_flavor = gcfMarlin; // << ??????????????????????? + else if (flavor == "Griffin") + m_flavor = gcfMarlin; // << ??????????????????????? + else if (flavor == "Repetier") + m_flavor = gcfRepetier; + else if (flavor == "RepRap") + m_flavor = gcfRepRap; + else if (flavor == "Marlin") + m_flavor = gcfMarlin; + else + BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown flavor: " << flavor; + + return true; + } + return false; } @@ -1582,7 +1739,7 @@ void GCodeProcessor::process_T(const std::string& command) else { unsigned char old_extruder_id = m_extruder_id; m_extruder_id = id; - m_cp_color.current = m_extruders_color[id]; + m_cp_color.current = m_extruder_colors[id]; // Specific to the MK3 MMU2: // The initial value of extruder_unloaded is set to true indicating // that the filament is parked in the MMU2 unit and there is nothing to be unloaded yet. diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 1def93e74..bad04100e 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -10,6 +10,7 @@ #include #include +#include namespace Slic3r { @@ -27,7 +28,7 @@ namespace Slic3r { private: using AxisCoords = std::array; - using ExtrudersColor = std::vector; + using ExtruderColors = std::vector; enum class EUnits : unsigned char { @@ -212,6 +213,7 @@ namespace Slic3r { std::vector moves; #if ENABLE_GCODE_VIEWER_AS_STATE Pointfs bed_shape; + std::vector extruder_colors; #endif // ENABLE_GCODE_VIEWER_AS_STATE #if ENABLE_GCODE_VIEWER_STATISTICS long long time{ 0 }; @@ -221,6 +223,7 @@ namespace Slic3r { moves = std::vector(); #if ENABLE_GCODE_VIEWER_AS_STATE bed_shape = Pointfs(); + extruder_colors = std::vector(); #endif // ENABLE_GCODE_VIEWER_AS_STATE } #else @@ -229,6 +232,7 @@ namespace Slic3r { moves = std::vector(); #if ENABLE_GCODE_VIEWER_AS_STATE bed_shape = Pointfs(); + extruder_colors = std::vector(); #endif // ENABLE_GCODE_VIEWER_AS_STATE } #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -255,7 +259,7 @@ namespace Slic3r { float m_fan_speed; // percentage ExtrusionRole m_extrusion_role; unsigned char m_extruder_id; - ExtrudersColor m_extruders_color; + ExtruderColors m_extruder_colors; std::vector m_filament_diameters; CpColor m_cp_color; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index af3d8d901..8d4fb6f4c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -43,13 +43,13 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { std::array decode_color(const std::string& color) { static const float INV_255 = 1.0f / 255.0f; - std::array ret; + std::array ret = { 0.0f, 0.0f, 0.0f }; const char* c = color.data() + 1; - if ((color.size() == 7) && (color.front() == '#')) { + if (color.size() == 7 && color.front() == '#') { for (size_t j = 0; j < 3; ++j) { int digit1 = hex_digit_to_int(*c++); int digit2 = hex_digit_to_int(*c++); - if ((digit1 == -1) || (digit2 == -1)) + if (digit1 == -1 || digit2 == -1) break; ret[j] = float(digit1 * 16 + digit2) * INV_255; @@ -351,8 +351,14 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: if (m_vertices_count == 0) return; - // update tool colors - m_tool_colors = decode_colors(str_tool_colors); +#if ENABLE_GCODE_VIEWER_AS_STATE + if (m_view_type == EViewType::Tool && !gcode_result.extruder_colors.empty()) + // update tool colors from config stored in the gcode + m_tool_colors = decode_colors(gcode_result.extruder_colors); + else +#endif // ENABLE_GCODE_VIEWER_AS_STATE + // update tool colors + m_tool_colors = decode_colors(str_tool_colors); // update ranges for coloring / legend m_extrusions.reset_ranges(); @@ -1708,7 +1714,6 @@ void GCodeViewer::render_time_estimate() const } #endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG - using Times = std::pair; using TimesList = std::vector>; using Headers = std::vector; diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 66e5ac487..fc6bc9891 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -204,7 +204,13 @@ void KBShortcutsDialog::fill_shortcuts() { "U", L("Upper Layer") }, { "D", L("Lower Layer") }, { "L", L("Show/Hide Legend") }, +#if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG + { "T", L("Show Estimated printing time") } +#else { "T", L("Show/Hide Estimated printing time") } +#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // ENABLE_GCODE_VIEWER }; m_full_shortcuts.push_back(std::make_pair(_L("Preview"), preview_shortcuts));