diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 51870e93d7..af28307faf 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -23,6 +23,10 @@ #include #include +#if ENABLE_BINARIZED_GCODE +#include +#endif // ENABLE_BINARIZED_GCODE + //FIXME for GCodeFlavor and gcfMarlin (for forward-compatibility conversion) // This is not nice, likely it would be better to pass the ConfigSubstitutionContext to handle_legacy(). #include "PrintConfig.hpp" @@ -720,11 +724,41 @@ void ConfigBase::setenv_() const } } -ConfigSubstitutions ConfigBase::load(const std::string &file, ForwardCompatibilitySubstitutionRule compatibility_rule) +ConfigSubstitutions ConfigBase::load(const std::string& filename, ForwardCompatibilitySubstitutionRule compatibility_rule) { - return is_gcode_file(file) ? - this->load_from_gcode_file(file, compatibility_rule) : - this->load_from_ini(file, compatibility_rule); +#if ENABLE_BINARIZED_GCODE + enum class EFileType + { + Ini, + AsciiGCode, + BinaryGCode + }; + + EFileType file_type; + + if (is_gcode_file(filename)) { + FILE* file = boost::nowide::fopen(filename.c_str(), "rb"); + if (file == nullptr) + throw Slic3r::RuntimeError("Error opening the file: " + filename + "\n"); + + file_type = (bgcode::core::is_valid_binary_gcode(*file, true) == bgcode::core::EResult::Success) ? EFileType::BinaryGCode : EFileType::AsciiGCode; + fclose(file); + } + else + file_type = EFileType::Ini; + + switch (file_type) + { + case EFileType::Ini: { return this->load_from_ini(filename, compatibility_rule); } + case EFileType::AsciiGCode: { return this->load_from_gcode_file(filename, compatibility_rule);} + case EFileType::BinaryGCode: { return this->load_from_binary_gcode_file(filename, compatibility_rule);} + default: { throw Slic3r::RuntimeError("Invalid file: " + filename + "\n"); } + } +#else + return is_gcode_file(filename) ? + this->load_from_gcode_file(filename, compatibility_rule) : + this->load_from_ini(filename, compatibility_rule); +#endif // ENABLE_BINARIZED_GCODE } ConfigSubstitutions ConfigBase::load_from_ini(const std::string &file, ForwardCompatibilitySubstitutionRule compatibility_rule) @@ -925,15 +959,15 @@ private: }; // Load the config keys from the tail of a G-code file. -ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, ForwardCompatibilitySubstitutionRule compatibility_rule) +ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &filename, ForwardCompatibilitySubstitutionRule compatibility_rule) { // Read a 64k block from the end of the G-code. - boost::nowide::ifstream ifs(file, std::ifstream::binary); + boost::nowide::ifstream ifs(filename, std::ifstream::binary); // Look for Slic3r or PrusaSlicer header. // Look for the header across the whole file as the G-code may have been extended at the start by a post-processing script or the user. bool has_delimiters = false; { - static constexpr const char slic3r_gcode_header[] = "; generated by Slic3r "; + static constexpr const char slic3r_gcode_header[] = "; generated by Slic3r "; static constexpr const char prusaslicer_gcode_header[] = "; generated by PrusaSlicer "; std::string header; bool header_found = false; @@ -983,7 +1017,7 @@ ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, Fo break; } if (! end_found) - throw Slic3r::RuntimeError(format("Configuration block closing tag \"; prusaslicer_config = end\" not found when reading %1%", file)); + throw Slic3r::RuntimeError(format("Configuration block closing tag \"; prusaslicer_config = end\" not found when reading %1%", filename)); std::string key, value; while (reader.getline(line)) { if (line == "; prusaslicer_config = begin") { @@ -1006,7 +1040,7 @@ ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, Fo } } if (! begin_found) - throw Slic3r::RuntimeError(format("Configuration block opening tag \"; prusaslicer_config = begin\" not found when reading %1%", file)); + throw Slic3r::RuntimeError(format("Configuration block opening tag \"; prusaslicer_config = begin\" not found when reading %1%", filename)); } else { @@ -1014,8 +1048,8 @@ ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, Fo // Try a heuristics reading the G-code from back. ifs.seekg(0, ifs.end); auto file_length = ifs.tellg(); - auto data_length = std::min(65535, file_length - header_end_pos); - ifs.seekg(file_length - data_length, ifs.beg); + auto data_length = std::min(65535, file_length - header_end_pos); + ifs.seekg(file_length - data_length, ifs.beg); std::vector data(size_t(data_length) + 1, 0); ifs.read(data.data(), data_length); ifs.close(); @@ -1023,10 +1057,52 @@ ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, Fo } if (key_value_pairs < 80) - throw Slic3r::RuntimeError(format("Suspiciously low number of configuration values extracted from %1%: %2%", file, key_value_pairs)); + throw Slic3r::RuntimeError(format("Suspiciously low number of configuration values extracted from %1%: %2%", filename, key_value_pairs)); return std::move(substitutions_ctxt.substitutions); } +#if ENABLE_BINARIZED_GCODE +ConfigSubstitutions ConfigBase::load_from_binary_gcode_file(const std::string& filename, ForwardCompatibilitySubstitutionRule compatibility_rule) +{ + ConfigSubstitutionContext substitutions_ctxt(compatibility_rule); + + FilePtr file{ boost::nowide::fopen(filename.c_str(), "rb") }; + if (file.f == nullptr) + throw Slic3r::RuntimeError(format("Error opening the file: %1%", filename)); + + bgcode::core::EResult res = bgcode::core::is_valid_binary_gcode(*file.f); + if (res != bgcode::core::EResult::Success) + throw Slic3r::RuntimeError(format("The selected file is not a valid binary gcode.\nError: %1%", + std::string(bgcode::core::translate_result(res)))); + + fseek(file.f, 0, SEEK_END); + const long file_size = ftell(file.f); + rewind(file.f); + + bgcode::core::FileHeader file_header; + res = bgcode::core::read_header(*file.f, file_header, nullptr); + if (res != bgcode::core::EResult::Success) + throw Slic3r::RuntimeError(format("Error while reading file '%1%': %2%", filename, std::string(bgcode::core::translate_result(res)))); + + bgcode::core::BlockHeader block_header; + res = read_next_block_header(*file.f, file_header, block_header, bgcode::core::EBlockType::SlicerMetadata, true); + if (res != bgcode::core::EResult::Success) + throw Slic3r::RuntimeError(format("Error while reading file '%1%': %2%", filename, std::string(bgcode::core::translate_result(res)))); + if ((bgcode::core::EBlockType)block_header.type != bgcode::core::EBlockType::SlicerMetadata) + throw Slic3r::RuntimeError(format("Unable to find slicer metadata block in file: '%1%'", filename)); + bgcode::base::SlicerMetadataBlock slicer_metadata_block; + res = slicer_metadata_block.read_data(*file.f, file_header, block_header); + if (res != bgcode::core::EResult::Success) + throw Slic3r::RuntimeError(format("Error while reading file '%1%': %2%", filename, std::string(bgcode::core::translate_result(res)))); + + for (const auto& [key, value] : slicer_metadata_block.raw_data) { + this->set_deserialize(key, value, substitutions_ctxt); + } + + return std::move(substitutions_ctxt.substitutions); +} +#endif // ENABLE_BINARIZED_GCODE + void ConfigBase::save(const std::string &file) const { boost::nowide::ofstream c; diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 28410b87dc..4995384203 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -2303,7 +2303,10 @@ public: // Loading a "will be one day a legacy format" of configuration stored into 3MF or AMF. // Accepts the same data as load_from_ini_string(), only with each configuration line possibly prefixed with a semicolon (G-code comment). ConfigSubstitutions load_from_ini_string_commented(std::string &&data, ForwardCompatibilitySubstitutionRule compatibility_rule); - ConfigSubstitutions load_from_gcode_file(const std::string &file, ForwardCompatibilitySubstitutionRule compatibility_rule); + ConfigSubstitutions load_from_gcode_file(const std::string &filename, ForwardCompatibilitySubstitutionRule compatibility_rule); +#if ENABLE_BINARIZED_GCODE + ConfigSubstitutions load_from_binary_gcode_file(const std::string& filename, ForwardCompatibilitySubstitutionRule compatibility_rule); +#endif // ENABLE_BINARIZED_GCODE ConfigSubstitutions load(const boost::property_tree::ptree &tree, ForwardCompatibilitySubstitutionRule compatibility_rule); void save(const std::string &file) const; diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 66f7cc297a..37ac7eb37a 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1122,34 +1122,23 @@ void GCodeProcessor::process_ascii_file(const std::string& filename, std::functi #if ENABLE_BINARIZED_GCODE void GCodeProcessor::process_binary_file(const std::string& filename, std::function cancel_callback) { - class ScopedFile - { - public: - explicit ScopedFile(FILE* file) : m_file(file) {} - ~ScopedFile() { if (m_file != nullptr) fclose(m_file); } - private: - FILE* m_file{ nullptr }; - }; - #if ENABLE_GCODE_VIEWER_STATISTICS m_start_time = std::chrono::high_resolution_clock::now(); #endif // ENABLE_GCODE_VIEWER_STATISTICS - FILE* file = boost::nowide::fopen(filename.c_str(), "rb"); - if (file == nullptr) + FilePtr file{ boost::nowide::fopen(filename.c_str(), "rb") }; + if (file.f == nullptr) throw Slic3r::RuntimeError("Unable to open file: " + filename + "\n"); - fseek(file, 0, SEEK_END); - const long file_size = ftell(file); - rewind(file); - - ScopedFile scoped_file(file); + fseek(file.f, 0, SEEK_END); + const long file_size = ftell(file.f); + rewind(file.f); bgcode::core::set_checksum_max_cache_size(1024); // read file header bgcode::core::FileHeader file_header; - bgcode::core::EResult res = bgcode::core::read_header(*file, file_header, nullptr); + bgcode::core::EResult res = bgcode::core::read_header(*file.f, file_header, nullptr); if (res != bgcode::core::EResult::Success) throw Slic3r::RuntimeError("File: " + filename + "does not contain a valid binary gcode\n Error: " + std::string(bgcode::core::translate_result(res)) + "\n"); @@ -1158,15 +1147,15 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct // read file metadata block bgcode::core::BlockHeader block_header; - res = bgcode::core::read_next_block_header(*file, file_header, block_header, verify_checksum); + res = bgcode::core::read_next_block_header(*file.f, file_header, block_header, verify_checksum); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); if ((bgcode::core::EBlockType)block_header.type != bgcode::core::EBlockType::FileMetadata) throw Slic3r::RuntimeError("Unable to find file metadata block in file: " + filename + "\n"); bgcode::base::FileMetadataBlock file_metadata_block; - res = file_metadata_block.read_data(*file, file_header, block_header); + res = file_metadata_block.read_data(*file.f, file_header, block_header); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); auto producer_it = std::find_if(file_metadata_block.raw_data.begin(), file_metadata_block.raw_data.end(), [](const std::pair& item) { return item.first == "Producer"; }); if (producer_it != file_metadata_block.raw_data.end() && boost::starts_with(producer_it->second, std::string(SLIC3R_APP_NAME))) @@ -1175,15 +1164,15 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct m_producer = EProducer::Unknown; // read printer metadata block - res = bgcode::core::read_next_block_header(*file, file_header, block_header, verify_checksum); + res = bgcode::core::read_next_block_header(*file.f, file_header, block_header, verify_checksum); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); if ((bgcode::core::EBlockType)block_header.type != bgcode::core::EBlockType::PrinterMetadata) throw Slic3r::RuntimeError("Unable to find printer metadata block in file: " + filename + "\n"); bgcode::base::PrinterMetadataBlock printer_metadata_block; - res = printer_metadata_block.read_data(*file, file_header, block_header); + res = printer_metadata_block.read_data(*file.f, file_header, block_header); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); #if ENABLE_BINARIZED_GCODE_DEBUG OutputDebugStringA("Printer metadata:\n"); for (const auto& [key, value] : printer_metadata_block.raw_data) { @@ -1195,15 +1184,15 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct #endif // ENABLE_BINARIZED_GCODE_DEBUG // read thumbnail blocks - res = bgcode::core::read_next_block_header(*file, file_header, block_header, verify_checksum); + res = bgcode::core::read_next_block_header(*file.f, file_header, block_header, verify_checksum); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); while ((bgcode::core::EBlockType)block_header.type == bgcode::core::EBlockType::Thumbnail) { bgcode::base::ThumbnailBlock thumbnail_block; - res = thumbnail_block.read_data(*file, file_header, block_header); + res = thumbnail_block.read_data(*file.f, file_header, block_header); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); #if ENABLE_BINARIZED_GCODE_DEBUG if (thumbnail_block.data.size() > 0) { auto format_filename = [](const std::string& stem, const bgcode::base::ThumbnailBlock& block) { @@ -1228,18 +1217,18 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct } #endif // ENABLE_BINARIZED_GCODE_DEBUG - res = bgcode::core::read_next_block_header(*file, file_header, block_header, verify_checksum); + res = bgcode::core::read_next_block_header(*file.f, file_header, block_header, verify_checksum); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); } // read print metadata block if ((bgcode::core::EBlockType)block_header.type != bgcode::core::EBlockType::PrintMetadata) throw Slic3r::RuntimeError("Unable to find print metadata block in file: " + filename + "\n"); bgcode::base::PrintMetadataBlock print_metadata_block; - res = print_metadata_block.read_data(*file, file_header, block_header); + res = print_metadata_block.read_data(*file.f, file_header, block_header); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); #if ENABLE_BINARIZED_GCODE_DEBUG OutputDebugStringA("Print metadata:\n"); for (const auto& [key, value] : print_metadata_block.raw_data) { @@ -1251,15 +1240,15 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct #endif // ENABLE_BINARIZED_GCODE_DEBUG // read slicer metadata block - res = bgcode::core::read_next_block_header(*file, file_header, block_header, verify_checksum); + res = bgcode::core::read_next_block_header(*file.f, file_header, block_header, verify_checksum); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); if ((bgcode::core::EBlockType)block_header.type != bgcode::core::EBlockType::SlicerMetadata) throw Slic3r::RuntimeError("Unable to find slicer metadata block in file: " + filename + "\n"); bgcode::base::SlicerMetadataBlock slicer_metadata_block; - res = slicer_metadata_block.read_data(*file, file_header, block_header); + res = slicer_metadata_block.read_data(*file.f, file_header, block_header); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); #if ENABLE_BINARIZED_GCODE_DEBUG OutputDebugStringA("Slicer metadata:\n"); for (const auto& [key, value] : slicer_metadata_block.raw_data) { @@ -1286,16 +1275,16 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct initialize_result_moves(); // read gcodes block - res = bgcode::core::read_next_block_header(*file, file_header, block_header, verify_checksum); + res = bgcode::core::read_next_block_header(*file.f, file_header, block_header, verify_checksum); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); if ((bgcode::core::EBlockType)block_header.type != bgcode::core::EBlockType::GCode) throw Slic3r::RuntimeError("Unable to find gcode block in file: " + filename + "\n"); while ((bgcode::core::EBlockType)block_header.type == bgcode::core::EBlockType::GCode) { bgcode::base::GCodeBlock block; - res = block.read_data(*file, file_header, block_header); + res = block.read_data(*file.f, file_header, block_header); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); // TODO: Update m_result.lines_ends @@ -1303,12 +1292,12 @@ void GCodeProcessor::process_binary_file(const std::string& filename, std::funct this->process_gcode_line(line, true); }); - if (ftell(file) == file_size) + if (ftell(file.f) == file_size) break; - res = bgcode::core::read_next_block_header(*file, file_header, block_header, verify_checksum); + res = bgcode::core::read_next_block_header(*file.f, file_header, block_header, verify_checksum); if (res != bgcode::core::EResult::Success) - throw Slic3r::RuntimeError("Error while reading file: " + filename + ": " + std::string(bgcode::core::translate_result(res)) + "\n"); + throw Slic3r::RuntimeError("Error while reading file '" + filename + "': " + std::string(bgcode::core::translate_result(res)) + "\n"); } // Don't post-process the G-code to update time stamps. diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 730574af13..45e4d0535f 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -22,6 +22,9 @@ #include #include +#if ENABLE_BINARIZED_GCODE +#include +#endif // ENABLE_BINARIZED_GCODE // Store the print/filament/printer presets into a "presets" subdirectory of the Slic3rPE config dir. // This breaks compatibility with the upstream Slic3r if the --datadir is used to switch between the two versions. @@ -875,14 +878,32 @@ DynamicPrintConfig PresetBundle::full_sla_config() const // If the file is loaded successfully, its print / filament / printer profiles will be activated. ConfigSubstitutions PresetBundle::load_config_file(const std::string &path, ForwardCompatibilitySubstitutionRule compatibility_rule) { - if (is_gcode_file(path)) { - DynamicPrintConfig config; - config.apply(FullPrintConfig::defaults()); +#if ENABLE_BINARIZED_GCODE + if (is_gcode_file(path)) { + FILE* file = boost::nowide::fopen(path.c_str(), "rb"); + if (file == nullptr) + throw Slic3r::RuntimeError("Error opening the file: " + path + "\n"); + const bool is_binary = bgcode::core::is_valid_binary_gcode(*file, true) == bgcode::core::EResult::Success; + fclose(file); + + DynamicPrintConfig config; + config.apply(FullPrintConfig::defaults()); + ConfigSubstitutions config_substitutions = is_binary ? config.load_from_binary_gcode_file(path, compatibility_rule) : + config.load_from_gcode_file(path, compatibility_rule); + Preset::normalize(config); + load_config_file_config(path, true, std::move(config)); + return config_substitutions; + } +#else + if (is_gcode_file(path)) { + DynamicPrintConfig config; + config.apply(FullPrintConfig::defaults()); ConfigSubstitutions config_substitutions = config.load_from_gcode_file(path, compatibility_rule); Preset::normalize(config); - load_config_file_config(path, true, std::move(config)); - return config_substitutions; - } + load_config_file_config(path, true, std::move(config)); + return config_substitutions; + } +#endif // ENABLE_BINARIZED_GCODE // 1) Try to load the config file into a boost property tree. boost::property_tree::ptree tree; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e0c1527e84..b9eb5a3c1c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5435,16 +5435,6 @@ void Plater::reload_gcode_from_disk() } #if ENABLE_BINARIZED_GCODE -class ScopedFile -{ -public: - explicit ScopedFile(FILE* file) : m_file(file) {} - ~ScopedFile() { if (m_file != nullptr) fclose(m_file); } - void unscope() { m_file = nullptr; } -private: - FILE* m_file{ nullptr }; -}; - void Plater::convert_gcode_to_ascii() { // Ask user for a gcode file name. @@ -5452,36 +5442,33 @@ void Plater::convert_gcode_to_ascii() wxGetApp().load_gcode(this, input_file); // Open source file - FILE* in_file = boost::nowide::fopen(into_u8(input_file).c_str(), "rb"); - if (in_file == nullptr) { + FilePtr in_file{ boost::nowide::fopen(into_u8(input_file).c_str(), "rb") }; + if (in_file.f == nullptr) { MessageDialog msg_dlg(this, _L("Unable to open the selected file."), _L("Error"), wxICON_ERROR | wxOK); msg_dlg.ShowModal(); return; } - ScopedFile scoped_in_file(in_file); // Set out filename boost::filesystem::path path(into_u8(input_file)); const std::string output_file = path.parent_path().string() + "/" + path.stem().string() + "_ascii" + path.extension().string(); // Open destination file - FILE* out_file = boost::nowide::fopen(output_file.c_str(), "wb"); - if (out_file == nullptr) { + FilePtr out_file{ boost::nowide::fopen(output_file.c_str(), "wb") }; + if (out_file.f == nullptr) { MessageDialog msg_dlg(this, _L("Unable to open output file."), _L("Error"), wxICON_ERROR | wxOK); msg_dlg.ShowModal(); return; } - ScopedFile scoped_out_file(out_file); // Perform conversion { wxBusyCursor busy; - bgcode::core::EResult res = bgcode::convert::from_binary_to_ascii(*in_file, *out_file, true); + bgcode::core::EResult res = bgcode::convert::from_binary_to_ascii(*in_file.f, *out_file.f, true); if (res != bgcode::core::EResult::Success) { MessageDialog msg_dlg(this, _L(std::string(bgcode::core::translate_result(res))), _L("Error converting gcode file"), wxICON_INFORMATION | wxOK); msg_dlg.ShowModal(); - scoped_out_file.unscope(); - fclose(out_file); + out_file.close(); boost::nowide::remove(output_file.c_str()); return; } @@ -5498,37 +5485,34 @@ void Plater::convert_gcode_to_binary() wxGetApp().load_gcode(this, input_file); // Open source file - FILE* in_file = boost::nowide::fopen(into_u8(input_file).c_str(), "rb"); - if (in_file == nullptr) { + FilePtr in_file{ boost::nowide::fopen(into_u8(input_file).c_str(), "rb") }; + if (in_file.f == nullptr) { MessageDialog msg_dlg(this, _L("Unable to open the selected file."), _L("Error"), wxICON_ERROR | wxOK); msg_dlg.ShowModal(); return; } - ScopedFile scoped_in_file(in_file); // Set out filename boost::filesystem::path path(into_u8(input_file)); const std::string output_file = path.parent_path().string() + "/" + path.stem().string() + "_binary" + path.extension().string(); // Open destination file - FILE* out_file = boost::nowide::fopen(output_file.c_str(), "wb"); - if (out_file == nullptr) { + FilePtr out_file{ boost::nowide::fopen(output_file.c_str(), "wb") }; + if (out_file.f == nullptr) { MessageDialog msg_dlg(this, _L("Unable to open output file."), _L("Error"), wxICON_ERROR | wxOK); msg_dlg.ShowModal(); return; } - ScopedFile scoped_out_file(out_file); // Perform conversion { wxBusyCursor busy; const bgcode::base::BinarizerConfig& binarizer_config = GCodeProcessor::get_binarizer_config(); - bgcode::core::EResult res = bgcode::convert::from_ascii_to_binary(*in_file, *out_file, binarizer_config); + bgcode::core::EResult res = bgcode::convert::from_ascii_to_binary(*in_file.f, *out_file.f, binarizer_config); if (res != bgcode::core::EResult::Success) { MessageDialog msg_dlg(this, _L(std::string(bgcode::core::translate_result(res))), _L("Error converting gcode file"), wxICON_INFORMATION | wxOK); msg_dlg.ShowModal(); - scoped_out_file.unscope(); - fclose(out_file); + out_file.close(); boost::nowide::remove(output_file.c_str()); return; }