mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-31 07:42:02 +08:00
Finish porting export_gcode() - atomic write and post-processing scripts
This commit is contained in:
parent
fac31616c8
commit
3b2c9cbf7d
@ -17,6 +17,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/nowide/args.hpp>
|
||||
#include <boost/nowide/iostream.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef USE_WX
|
||||
#include "GUI/GUI.hpp"
|
||||
@ -48,8 +49,6 @@ int CLI::run(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: validate this->config (min, max etc.)
|
||||
|
||||
// parse actions and transform options
|
||||
for (auto const &opt_key : opt_order) {
|
||||
if (cli_actions_config_def.has(opt_key)) this->actions.push_back(opt_key);
|
||||
@ -293,7 +292,7 @@ int CLI::run(int argc, char **argv) {
|
||||
const std::string outfile = this->output_filepath(model, IO::Gcode);
|
||||
try {
|
||||
print.export_gcode(outfile);
|
||||
} catch (InvalidPrintException &e) {
|
||||
} catch (std::runtime_error &e) {
|
||||
boost::nowide::cerr << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
@ -9,7 +9,17 @@
|
||||
#include <algorithm>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef __cpp_lib_quoted_string_io
|
||||
#include <iomanip>
|
||||
#else
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -717,7 +727,6 @@ Print::export_gcode(std::ostream& output, bool quiet)
|
||||
|
||||
auto export_handler {Slic3r::PrintGCode(*this, output)};
|
||||
export_handler.output();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -726,10 +735,46 @@ Print::export_gcode(std::string outfile, bool quiet)
|
||||
// compute the actual output filepath
|
||||
outfile = this->output_filepath(outfile);
|
||||
|
||||
std::ofstream outstream(outfile);
|
||||
// write G-code to a temporary file in order to make the export atomic
|
||||
const std::string tempfile{ outfile + ".tmp" };
|
||||
std::ofstream outstream(tempfile);
|
||||
this->export_gcode(outstream);
|
||||
|
||||
// TODO: export_gcode() is not ported completely from Perl
|
||||
// rename the temporary file to the destination file
|
||||
// When renaming, some other application (thank you, Windows Explorer)
|
||||
// may keep the file locked. Try to wait a bit and then rename the file again.
|
||||
for (int i = 0; std::rename(tempfile.c_str(), outfile.c_str()) != 0; ++i) {
|
||||
if (i == 4) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed to remove the output G-code file from "
|
||||
<< tempfile << " to " << outfile << ". Is " << tempfile << " locked?";
|
||||
throw std::runtime_error(ss.str());
|
||||
} else {
|
||||
// Wait for 1/4 seconds and try to rename once again.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
}
|
||||
}
|
||||
|
||||
// run post-processing scripts
|
||||
if (!this->config.post_process.values.empty()) {
|
||||
if (this->status_cb != nullptr)
|
||||
this->status_cb(95, "Running post-processing scripts...");
|
||||
|
||||
this->config.setenv_();
|
||||
for (std::string ppscript : this->config.post_process.values) {
|
||||
#ifdef __cpp_lib_quoted_string_io
|
||||
ppscript += " " + std::quoted(outfile);
|
||||
#else
|
||||
boost::replace_all(ppscript, "\"", "\\\"");
|
||||
ppscript += " \"" + outfile + "\"";
|
||||
#endif
|
||||
system(ppscript.c_str());
|
||||
|
||||
// TODO: system() should be only used if user enabled an option for explicitly
|
||||
// supporting arguments, otherwise we should use exec*() and call the executable
|
||||
// directly without launching a shell. #4000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user