diff options
Diffstat (limited to 'xs/src/libslic3r/GCode.cpp')
-rw-r--r-- | xs/src/libslic3r/GCode.cpp | 98 |
1 files changed, 80 insertions, 18 deletions
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index d42a61290..080b4769d 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -13,6 +13,7 @@ #include <boost/algorithm/string.hpp> #include <boost/algorithm/string/find.hpp> #include <boost/foreach.hpp> +#include <boost/log/trivial.hpp> #include <boost/nowide/iostream.hpp> #include <boost/nowide/cstdio.hpp> @@ -348,10 +349,12 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec return layers_to_print; } -void GCode::do_export(Print *print, const char *path) +void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) { PROFILE_CLEAR(); + BOOST_LOG_TRIVIAL(info) << "Exporting G-code..."; + // Remove the old g-code if it exists. boost::nowide::remove(path); @@ -363,7 +366,7 @@ void GCode::do_export(Print *print, const char *path) throw std::runtime_error(std::string("G-code export to ") + path + " failed.\nCannot open the file for writing.\n"); this->m_placeholder_parser_failed_templates.clear(); - this->_do_export(*print, file); + this->_do_export(*print, file, preview_data); fflush(file); if (ferror(file)) { fclose(file); @@ -389,12 +392,14 @@ void GCode::do_export(Print *print, const char *path) std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + path + '\n' + "Is " + path_tmp + " locked?" + '\n'); + BOOST_LOG_TRIVIAL(info) << "Exporting G-code finished"; + // Write the profiler measurements to file PROFILE_UPDATE(); PROFILE_OUTPUT(debug_out_path("gcode-export-profile.txt").c_str()); } -void GCode::_do_export(Print &print, FILE *file) +void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) { PROFILE_FUNC(); @@ -402,6 +407,15 @@ void GCode::_do_export(Print &print, FILE *file) m_time_estimator.reset(); m_time_estimator.set_dialect(print.config.gcode_flavor); + // resets analyzer + m_analyzer.reset(); + m_enable_analyzer = preview_data != nullptr; + + // resets analyzer's tracking data + m_last_mm3_per_mm = GCodeAnalyzer::Default_mm3_per_mm; + m_last_width = GCodeAnalyzer::Default_Width; + m_last_height = GCodeAnalyzer::Default_Height; + // How many times will be change_layer() called? // change_layer() in turn increments the progress bar status. m_layer_count = 0; @@ -762,7 +776,7 @@ void GCode::_do_export(Print &print, FILE *file) _writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id())); } else { for (const std::string &end_gcode : print.config.end_filament_gcode.values) - _writeln(file, this->placeholder_parser_process("end_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()))); + _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()))); } _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id())); _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% @@ -807,6 +821,10 @@ void GCode::_do_export(Print &print, FILE *file) if (!full_config.empty()) _write(file, full_config); } + + // starts analizer calculations + if (preview_data != nullptr) + m_analyzer.calc_gcode_preview_data(*preview_data); } std::string GCode::placeholder_parser_process(const std::string &name, const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override) @@ -1298,12 +1316,7 @@ void GCode::process_layer( if (print_object == nullptr) // This layer is empty for this particular object, it has neither object extrusions nor support extrusions at this print_z. continue; - if (m_enable_analyzer_markers) { - // Store the binary pointer to the layer object directly into the G-code to be accessed by the GCodeAnalyzer. - char buf[64]; - sprintf(buf, ";_LAYEROBJ:%p\n", m_layer); - gcode += buf; - } + m_config.apply(print_object->config, true); m_layer = layers[layer_id].layer(); if (m_config.avoid_crossing_perimeters) @@ -1463,7 +1476,9 @@ static inline const char* ExtrusionRole2String(const ExtrusionRole role) case erSkirt: return "erSkirt"; case erSupportMaterial: return "erSupportMaterial"; case erSupportMaterialInterface: return "erSupportMaterialInterface"; + case erWipeTower: return "erWipeTower"; case erMixed: return "erMixed"; + default: return "erInvalid"; }; } @@ -2013,13 +2028,16 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill return gcode; } -void GCode::_write(FILE* file, const char *what, size_t size) +void GCode::_write(FILE* file, const char *what) { - if (size > 0) { + if (what != nullptr) { + // apply analyzer, if enabled + const char* gcode = m_enable_analyzer ? m_analyzer.process_gcode(what).c_str() : what; + // writes string to file - fwrite(what, 1, size, file); + fwrite(gcode, 1, ::strlen(gcode), file); // updates time estimator and gcode lines vector - m_time_estimator.add_gcode_block(what); + m_time_estimator.add_gcode_block(gcode); } } @@ -2053,7 +2071,8 @@ void GCode::_write_format(FILE* file, const char* format, ...) char *bufptr = buffer_dynamic ? (char*)malloc(buflen) : buffer; int res = ::vsnprintf(bufptr, buflen, format, args); if (res > 0) - _write(file, bufptr, res); + _write(file, bufptr); + if (buffer_dynamic) free(bufptr); @@ -2138,14 +2157,57 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double F = speed * 60; // convert mm/sec to mm/min // extrude arc or line - if (m_enable_extrusion_role_markers || m_enable_analyzer_markers) { - if (path.role() != m_last_extrusion_role) { + if (m_enable_extrusion_role_markers || m_enable_analyzer) + { + if (path.role() != m_last_extrusion_role) + { m_last_extrusion_role = path.role(); + if (m_enable_extrusion_role_markers) + { + char buf[32]; + sprintf(buf, ";_EXTRUSION_ROLE:%d\n", int(m_last_extrusion_role)); + gcode += buf; + } + if (m_enable_analyzer) + { + char buf[32]; + sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_extrusion_role)); + gcode += buf; + } + } + } + + // adds analyzer tags and updates analyzer's tracking data + if (m_enable_analyzer) + { + if (m_last_mm3_per_mm != path.mm3_per_mm) + { + m_last_mm3_per_mm = path.mm3_per_mm; + char buf[32]; - sprintf(buf, ";_EXTRUSION_ROLE:%d\n", int(path.role())); + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); + gcode += buf; + } + + if (m_last_width != path.width) + { + m_last_width = path.width; + + char buf[32]; + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); + gcode += buf; + } + + if (m_last_height != path.height) + { + m_last_height = path.height; + + char buf[32]; + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_last_height); gcode += buf; } } + std::string comment; if (m_enable_cooling_markers) { if (is_bridge(path.role())) |