diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/admesh/stlinit.cpp | 4 | ||||
-rw-r--r-- | src/libslic3r/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/libslic3r/GCode/Analyzer.cpp | 5 | ||||
-rw-r--r-- | src/libslic3r/SLA/SLARaster.hpp | 13 | ||||
-rw-r--r-- | src/libslic3r/SLA/SLARasterWriter.cpp | 107 | ||||
-rw-r--r-- | src/libslic3r/SLA/SLARasterWriter.hpp | 109 | ||||
-rw-r--r-- | src/libslic3r/SLAPrint.cpp | 76 | ||||
-rw-r--r-- | src/libslic3r/SLAPrint.hpp | 14 | ||||
-rw-r--r-- | src/libslic3r/Time.cpp (renamed from src/slic3r/Utils/Time.cpp) | 68 | ||||
-rw-r--r-- | src/libslic3r/Time.hpp | 47 | ||||
-rw-r--r-- | src/libslic3r/Utils.hpp | 4 | ||||
-rw-r--r-- | src/libslic3r/utils.cpp | 14 | ||||
-rw-r--r-- | src/slic3r/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/slic3r/Config/Snapshot.cpp | 2 | ||||
-rw-r--r-- | src/slic3r/GUI/ConfigSnapshotDialog.cpp | 2 | ||||
-rw-r--r-- | src/slic3r/GUI/Plater.cpp | 3 | ||||
-rw-r--r-- | src/slic3r/Utils/Time.hpp | 25 |
17 files changed, 280 insertions, 217 deletions
diff --git a/src/admesh/stlinit.cpp b/src/admesh/stlinit.cpp index bbf6d3dd5..693aad086 100644 --- a/src/admesh/stlinit.cpp +++ b/src/admesh/stlinit.cpp @@ -179,12 +179,12 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first) // Some G-code generators tend to produce text after "endloop" and "endfacet". Just ignore it. char buf[2048]; fgets(buf, 2047, fp); - bool endloop_ok = strncmp(buf, "endloop", 7) == 0 && (buf[7] == '\n' || buf[7] == ' ' || buf[7] == '\t'); + bool endloop_ok = strncmp(buf, "endloop", 7) == 0 && (buf[7] == '\r' || buf[7] == '\n' || buf[7] == ' ' || buf[7] == '\t'); assert(endloop_ok); // Skip the trailing whitespaces and empty lines. fscanf(fp, " "); fgets(buf, 2047, fp); - bool endfacet_ok = strncmp(buf, "endfacet", 8) == 0 && (buf[8] == '\n' || buf[8] == ' ' || buf[8] == '\t'); + bool endfacet_ok = strncmp(buf, "endfacet", 8) == 0 && (buf[8] == '\r' || buf[8] == '\n' || buf[8] == ' ' || buf[8] == '\t'); assert(endfacet_ok); if (res_normal != 3 || res_outer_loop != 0 || res_vertex1 != 3 || res_vertex2 != 3 || res_vertex3 != 3 || ! endloop_ok || ! endfacet_ok) { BOOST_LOG_TRIVIAL(error) << "Something is syntactically very wrong with this ASCII STL! "; diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 85e11eded..97e0fc09b 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -165,6 +165,8 @@ add_library(libslic3r STATIC TriangleMesh.hpp utils.cpp Utils.hpp + Time.cpp + Time.hpp MTUtils.hpp Zipper.hpp Zipper.cpp diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index 5250c90b0..20f0483b0 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -529,7 +529,10 @@ void GCodeAnalyzer::_processT(const std::string& cmd) if (_get_extruder_id() != id) { if (id >= m_extruders_count) - BOOST_LOG_TRIVIAL(error) << "GCodeAnalyzer encountered an invalid toolchange, maybe from a custom gcode."; + { + if (m_extruders_count > 1) + BOOST_LOG_TRIVIAL(error) << "GCodeAnalyzer encountered an invalid toolchange, maybe from a custom gcode."; + } else _set_extruder_id(id); diff --git a/src/libslic3r/SLA/SLARaster.hpp b/src/libslic3r/SLA/SLARaster.hpp index d3bd52d92..8b27fd153 100644 --- a/src/libslic3r/SLA/SLARaster.hpp +++ b/src/libslic3r/SLA/SLARaster.hpp @@ -68,15 +68,14 @@ public: /// Type that represents a resolution in pixels. struct Resolution { - unsigned width_px; - unsigned height_px; + size_t width_px; + size_t height_px; - inline Resolution(unsigned w = 0, unsigned h = 0): - width_px(w), height_px(h) {} + inline Resolution(size_t w = 0, size_t h = 0) + : width_px(w), height_px(h) + {} - inline unsigned pixels() const /*noexcept*/ { - return width_px * height_px; - } + inline size_t pixels() const { return width_px * height_px; } }; /// Types that represents the dimension of a pixel in millimeters. diff --git a/src/libslic3r/SLA/SLARasterWriter.cpp b/src/libslic3r/SLA/SLARasterWriter.cpp index f7c3925ac..3e6f015d4 100644 --- a/src/libslic3r/SLA/SLARasterWriter.cpp +++ b/src/libslic3r/SLA/SLARasterWriter.cpp @@ -1,5 +1,7 @@ #include "SLARasterWriter.hpp" #include "libslic3r/Zipper.hpp" +#include "libslic3r/Time.hpp" + #include "ExPolygon.hpp" #include <libnest2d/backends/clipper/clipper_polygon.hpp> @@ -10,25 +12,13 @@ namespace Slic3r { namespace sla { std::string SLARasterWriter::createIniContent(const std::string& projectname) const { - auto expt_str = std::to_string(m_exp_time_s); - auto expt_first_str = std::to_string(m_exp_time_first_s); - auto layerh_str = std::to_string(m_layer_height); - - const std::string cnt_fade_layers = std::to_string(m_cnt_fade_layers); - const std::string cnt_slow_layers = std::to_string(m_cnt_slow_layers); - const std::string cnt_fast_layers = std::to_string(m_cnt_fast_layers); - const std::string used_material = std::to_string(m_used_material); - - return std::string( - "action = print\n" - "jobDir = ") + projectname + "\n" + - "expTime = " + expt_str + "\n" - "expTimeFirst = " + expt_first_str + "\n" - "numFade = " + cnt_fade_layers + "\n" - "layerHeight = " + layerh_str + "\n" - "usedMaterial = " + used_material + "\n" - "numSlow = " + cnt_slow_layers + "\n" - "numFast = " + cnt_fast_layers + "\n"; + std::string out("action = print\njobDir = "); + out += projectname + "\n"; + + for (auto ¶m : m_config) + out += param.first + " = " + param.second + "\n"; + + return out; } void SLARasterWriter::flpXY(ClipperLib::Polygon &poly) @@ -53,38 +43,14 @@ void SLARasterWriter::flpXY(ExPolygon &poly) } } -SLARasterWriter::SLARasterWriter(const SLAPrinterConfig &cfg, - const SLAMaterialConfig &mcfg, - double layer_height) +SLARasterWriter::SLARasterWriter(const Raster::Resolution &res, + const Raster::PixelDim &pixdim, + const std::array<bool, 2> &mirror, + double gamma) + : m_res(res), m_pxdim(pixdim), m_mirror(mirror), m_gamma(gamma) { - double w = cfg.display_width.getFloat(); - double h = cfg.display_height.getFloat(); - auto pw = unsigned(cfg.display_pixels_x.getInt()); - auto ph = unsigned(cfg.display_pixels_y.getInt()); - - m_mirror[X] = cfg.display_mirror_x.getBool(); - // PNG raster will implicitly do an Y mirror - m_mirror[Y] = ! cfg.display_mirror_y.getBool(); - - auto ro = cfg.display_orientation.getInt(); - - if(ro == roPortrait) { - std::swap(w, h); - std::swap(pw, ph); - m_o = roPortrait; - - // XY flipping implicitly does an X mirror - m_mirror[X] = ! m_mirror[X]; - } else m_o = roLandscape; - - m_res = Raster::Resolution(pw, ph); - m_pxdim = Raster::PixelDim(w/pw, h/ph); - m_exp_time_s = mcfg.exposure_time.getFloat(); - m_exp_time_first_s = mcfg.initial_exposure_time.getFloat(); - m_layer_height = layer_height; - - m_gamma = cfg.gamma_correction.getFloat(); + m_mirror[1] = !m_mirror[1]; } void SLARasterWriter::save(const std::string &fpath, const std::string &prjname) @@ -121,15 +87,44 @@ void SLARasterWriter::save(const std::string &fpath, const std::string &prjname) } } -void SLARasterWriter::set_statistics(const std::vector<double> statistics) +namespace { + +std::string get_cfg_value(const DynamicPrintConfig &cfg, const std::string &key) { - if (statistics.size() != psCnt) - return; + std::string ret; + + if (cfg.has(key)) { + auto opt = cfg.option(key); + if (opt) ret = opt->serialize(); + } - m_used_material = statistics[psUsedMaterial]; - m_cnt_fade_layers = int(statistics[psNumFade]); - m_cnt_slow_layers = int(statistics[psNumSlow]); - m_cnt_fast_layers = int(statistics[psNumFast]); + return ret; +} + +} // namespace + +void SLARasterWriter::set_config(const DynamicPrintConfig &cfg) +{ + m_config["layerHeight"] = get_cfg_value(cfg, "layer_height"); + m_config["expTime"] = get_cfg_value(cfg, "exposure_time"); + m_config["expTimeFirst"] = get_cfg_value(cfg, "initial_exposure_time"); + m_config["materialName"] = get_cfg_value(cfg, "sla_material_settings_id"); + m_config["printerModel"] = get_cfg_value(cfg, "printer_model"); + m_config["printerVariant"] = get_cfg_value(cfg, "printer_variant"); + m_config["printerProfile"] = get_cfg_value(cfg, "printer_settings_id"); + m_config["printProfile"] = get_cfg_value(cfg, "sla_print_settings_id"); + + m_config["fileCreationTimestamp"] = Utils::current_utc_time2str(); + m_config["prusaSlicerVersion"] = SLIC3R_BUILD_ID; +} + +void SLARasterWriter::set_statistics(const PrintStatistics &stats) +{ + m_config["usedMaterial"] = std::to_string(stats.used_material); + m_config["numFade"] = std::to_string(stats.num_fade); + m_config["numSlow"] = std::to_string(stats.num_slow); + m_config["numFast"] = std::to_string(stats.num_fast); + m_config["printTime"] = std::to_string(stats.estimated_print_time_s); } } // namespace sla diff --git a/src/libslic3r/SLA/SLARasterWriter.hpp b/src/libslic3r/SLA/SLARasterWriter.hpp index 7133d2dde..b9202c464 100644 --- a/src/libslic3r/SLA/SLARasterWriter.hpp +++ b/src/libslic3r/SLA/SLARasterWriter.hpp @@ -3,8 +3,10 @@ // For png export of the sliced model #include <fstream> +#include <string> #include <sstream> #include <vector> +#include <map> #include <array> #include "libslic3r/PrintConfig.hpp" @@ -23,20 +25,19 @@ namespace Slic3r { namespace sla { class SLARasterWriter { public: - enum RasterOrientation { + enum Orientation { roLandscape, roPortrait }; // Used for addressing parameters of set_statistics() - enum ePrintStatistics - { - psUsedMaterial = 0, - psNumFade, - psNumSlow, - psNumFast, - - psCnt + struct PrintStatistics + { + double used_material = 0.; + double estimated_print_time_s = 0.; + size_t num_fade = 0; + size_t num_slow = 0; + size_t num_fast = 0; }; private: @@ -47,21 +48,13 @@ private: RawBytes rawbytes; Layer() = default; - Layer(const Layer&) = delete; // The image is big, do not copy by accident - Layer& operator=(const Layer&) = delete; - // ///////////////////////////////////////////////////////////////////// - // FIXME: the following is needed for MSVC2013 compatibility - // ///////////////////////////////////////////////////////////////////// - - // Layer(Layer&& m) = default; - // Layer& operator=(Layer&&) = default; - Layer(Layer &&m): - raster(std::move(m.raster)), rawbytes(std::move(m.rawbytes)) {} - Layer& operator=(Layer &&m) { - raster = std::move(m.raster); rawbytes = std::move(m.rawbytes); - return *this; - } + // The image is big, do not copy by accident + Layer(const Layer&) = delete; + Layer& operator=(const Layer&) = delete; + + Layer(Layer &&m) = default; + Layer &operator=(Layer &&) = default; }; // We will save the compressed PNG data into RawBytes type buffers in @@ -69,66 +62,46 @@ private: std::vector<Layer> m_layers_rst; Raster::Resolution m_res; Raster::PixelDim m_pxdim; - double m_exp_time_s = .0, m_exp_time_first_s = .0; - double m_layer_height = .0; - RasterOrientation m_o = roPortrait; std::array<bool, 2> m_mirror; - double m_gamma; - - double m_used_material = 0.0; - int m_cnt_fade_layers = 0; - int m_cnt_slow_layers = 0; - int m_cnt_fast_layers = 0; - + + std::map<std::string, std::string> m_config; + std::string createIniContent(const std::string& projectname) const; static void flpXY(ClipperLib::Polygon& poly); static void flpXY(ExPolygon& poly); public: - - SLARasterWriter(const SLAPrinterConfig& cfg, - const SLAMaterialConfig& mcfg, - double layer_height); + SLARasterWriter(const Raster::Resolution &res, + const Raster::PixelDim &pixdim, + const std::array<bool, 2> &mirror, + double gamma = 1.); SLARasterWriter(const SLARasterWriter& ) = delete; SLARasterWriter& operator=(const SLARasterWriter&) = delete; - - // ///////////////////////////////////////////////////////////////////////// - // FIXME: the following is needed for MSVC2013 compatibility - // ///////////////////////////////////////////////////////////////////////// - - // SLARasterWriter(SLARasterWriter&& m) = default; - // SLARasterWriter& operator=(SLARasterWriter&&) = default; - SLARasterWriter(SLARasterWriter&& m): - m_layers_rst(std::move(m.m_layers_rst)), - m_res(m.m_res), - m_pxdim(m.m_pxdim), - m_exp_time_s(m.m_exp_time_s), - m_exp_time_first_s(m.m_exp_time_first_s), - m_layer_height(m.m_layer_height), - m_o(m.m_o), - m_mirror(std::move(m.m_mirror)), - m_gamma(m.m_gamma), - m_used_material(m.m_used_material), - m_cnt_fade_layers(m.m_cnt_fade_layers), - m_cnt_slow_layers(m.m_cnt_slow_layers), - m_cnt_fast_layers(m.m_cnt_fast_layers) - {} - - // ///////////////////////////////////////////////////////////////////////// + SLARasterWriter(SLARasterWriter&& m) = default; + SLARasterWriter& operator=(SLARasterWriter&&) = default; inline void layers(unsigned cnt) { if(cnt > 0) m_layers_rst.resize(cnt); } inline unsigned layers() const { return unsigned(m_layers_rst.size()); } - template<class Poly> void draw_polygon(const Poly& p, unsigned lyr) { + template<class Poly> void draw_polygon(const Poly& p, unsigned lyr, + Orientation o = roPortrait) + { assert(lyr < m_layers_rst.size()); - if(m_o == roPortrait) { - Poly poly(p); flpXY(poly); + + switch (o) { + case roPortrait: { + Poly poly(p); + flpXY(poly); m_layers_rst[lyr].raster.draw(poly); + break; + } + case roLandscape: + m_layers_rst[lyr].raster.draw(p); + break; } - else m_layers_rst[lyr].raster.draw(p); } inline void begin_layer(unsigned lyr) { @@ -156,9 +129,11 @@ public: } } - void save(const std::string& fpath, const std::string& prjname = ""); + void save(const std::string &fpath, const std::string &prjname = ""); - void set_statistics(const std::vector<double> statistics); + void set_statistics(const PrintStatistics &statistics); + + void set_config(const DynamicPrintConfig &cfg); }; } // namespace sla diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 30d6fc7c3..46d039c1f 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1381,9 +1381,9 @@ void SLAPrint::process() // Estimated printing time // A layers count o the highest object if (m_printer_input.size() == 0) - m_print_statistics.estimated_print_time = "N/A"; + m_print_statistics.estimated_print_time = std::nan(""); else - m_print_statistics.estimated_print_time = get_time_dhms(float(estim_time)); + m_print_statistics.estimated_print_time = estim_time; m_print_statistics.fast_layers_count = fast_layers; m_print_statistics.slow_layers_count = slow_layers; @@ -1394,16 +1394,9 @@ void SLAPrint::process() // Rasterizing the model objects, and their supports auto rasterize = [this]() { if(canceled()) return; - - { // create a raster printer for the current print parameters - double layerh = m_default_object_config.layer_height.getFloat(); - m_printer.reset(new sla::SLARasterWriter(m_printer_config, - m_material_config, - layerh)); - } - - // Allocate space for all the layers - sla::SLARasterWriter &printer = *m_printer; + + // Set up the printer, allocate space for all the layers + sla::SLARasterWriter &printer = init_printer(); auto lvlcnt = unsigned(m_printer_input.size()); printer.layers(lvlcnt); @@ -1422,10 +1415,12 @@ void SLAPrint::process() double dstatus = m_report_status.status(); SpinMutex slck; + + auto orientation = get_printer_orientation(); // procedure to process one height level. This will run in parallel auto lvlfn = - [this, &slck, &printer, increment, &dstatus, &pst] + [this, &slck, &printer, increment, &dstatus, &pst, orientation] (unsigned level_id) { if(canceled()) return; @@ -1436,7 +1431,7 @@ void SLAPrint::process() printer.begin_layer(level_id); for(const ClipperLib::Polygon& poly : printlayer.transformed_slices()) - printer.draw_polygon(poly, level_id); + printer.draw_polygon(poly, level_id, orientation); // Finish the layer for later saving it. printer.finish_layer(level_id); @@ -1464,12 +1459,18 @@ void SLAPrint::process() tbb::parallel_for<unsigned, decltype(lvlfn)>(0, lvlcnt, lvlfn); // Set statistics values to the printer - m_printer->set_statistics( - {(m_print_statistics.objects_used_material - + m_print_statistics.support_used_material) / 1000, - double(m_default_object_config.faded_layers.getInt()), - double(m_print_statistics.slow_layers_count), - double(m_print_statistics.fast_layers_count)}); + sla::SLARasterWriter::PrintStatistics stats; + stats.used_material = (m_print_statistics.objects_used_material + + m_print_statistics.support_used_material) / + 1000; + + int num_fade = m_default_object_config.faded_layers.getInt(); + stats.num_fade = num_fade >= 0 ? size_t(num_fade) : size_t(0); + stats.num_fast = m_print_statistics.fast_layers_count; + stats.num_slow = m_print_statistics.slow_layers_count; + stats.estimated_print_time_s = m_print_statistics.estimated_print_time; + + m_printer->set_statistics(stats); }; using slaposFn = std::function<void(SLAPrintObject&)>; @@ -1653,6 +1654,39 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_opt return invalidated; } +sla::SLARasterWriter & SLAPrint::init_printer() +{ + sla::Raster::Resolution res; + sla::Raster::PixelDim pxdim; + std::array<bool, 2> mirror; + double gamma; + + double w = m_printer_config.display_width.getFloat(); + double h = m_printer_config.display_height.getFloat(); + auto pw = size_t(m_printer_config.display_pixels_x.getInt()); + auto ph = size_t(m_printer_config.display_pixels_y.getInt()); + + mirror[X] = m_printer_config.display_mirror_x.getBool(); + mirror[Y] = m_printer_config.display_mirror_y.getBool(); + + if (get_printer_orientation() == sla::SLARasterWriter::roPortrait) { + std::swap(w, h); + std::swap(pw, ph); + + // XY flipping implicitly does an X mirror + mirror[X] = !mirror[X]; + } + + res = sla::Raster::Resolution{pw, ph}; + pxdim = sla::Raster::PixelDim{w / pw, h / ph}; + + gamma = m_printer_config.gamma_correction.getFloat(); + + m_printer.reset(new sla::SLARasterWriter(res, pxdim, mirror, gamma)); + m_printer->set_config(m_full_print_config); + return *m_printer; +} + // Returns true if an object step is done on all objects and there's at least one object. bool SLAPrint::is_step_done(SLAPrintObjectStep step) const { @@ -1932,7 +1966,7 @@ std::vector<sla::SupportPoint> SLAPrintObject::transformed_support_points() cons DynamicConfig SLAPrintStatistics::config() const { DynamicConfig config; - const std::string print_time = Slic3r::short_time(this->estimated_print_time); + const std::string print_time = Slic3r::short_time(get_time_dhms(float(this->estimated_print_time))); config.set_key_value("print_time", new ConfigOptionString(print_time)); config.set_key_value("objects_used_material", new ConfigOptionFloat(this->objects_used_material)); config.set_key_value("support_used_material", new ConfigOptionFloat(this->support_used_material)); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index ec3b2d02e..a2bc1325a 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -300,7 +300,7 @@ class TriangleMesh; struct SLAPrintStatistics { SLAPrintStatistics() { clear(); } - std::string estimated_print_time; + double estimated_print_time; double objects_used_material; double support_used_material; size_t slow_layers_count; @@ -316,7 +316,7 @@ struct SLAPrintStatistics std::string finalize_output_path(const std::string &path_in) const; void clear() { - estimated_print_time.clear(); + estimated_print_time = 0.; objects_used_material = 0.; support_used_material = 0.; slow_layers_count = 0; @@ -458,6 +458,16 @@ private: double status() const { return m_st; } } m_report_status; + + sla::SLARasterWriter &init_printer(); + + inline sla::SLARasterWriter::Orientation get_printer_orientation() const + { + auto ro = m_printer_config.display_orientation.getInt(); + return ro == sla::SLARasterWriter::roPortrait ? + sla::SLARasterWriter::roPortrait : + sla::SLARasterWriter::roLandscape; + } friend SLAPrintObject; }; diff --git a/src/slic3r/Utils/Time.cpp b/src/libslic3r/Time.cpp index db1aa31f6..1f65189b8 100644 --- a/src/slic3r/Utils/Time.cpp +++ b/src/libslic3r/Time.cpp @@ -1,5 +1,13 @@ #include "Time.hpp" +#include <iomanip> +#include <sstream> +#include <chrono> + +//#include <boost/date_time/local_time/local_time.hpp> +//#include <boost/chrono.hpp> + + #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include <windows.h> @@ -9,11 +17,31 @@ namespace Slic3r { namespace Utils { +namespace { + +// FIXME: after we switch to gcc > 4.9 on the build server, please remove me +#if defined(__GNUC__) && __GNUC__ <= 4 +std::string put_time(const std::tm *tm, const char *fmt) +{ + static const constexpr int MAX_CHARS = 200; + char out[MAX_CHARS]; + std::strftime(out, MAX_CHARS, fmt, tm); + return out; +} +#else +auto put_time(const std::tm *tm, const char *fmt) -> decltype (std::put_time(tm, fmt)) +{ + return std::put_time(tm, fmt); +} +#endif + +} + time_t parse_time_ISO8601Z(const std::string &sdate) { int y, M, d, h, m, s; if (sscanf(sdate.c_str(), "%04d%02d%02dT%02d%02d%02dZ", &y, &M, &d, &h, &m, &s) != 6) - return (time_t)-1; + return time_t(-1); struct tm tms; tms.tm_year = y - 1900; // Year since 1900 tms.tm_mon = M - 1; // 0-11 @@ -62,24 +90,28 @@ std::string format_local_date_time(time_t time) } time_t get_current_time_utc() +{ + using clk = std::chrono::system_clock; + return clk::to_time_t(clk::now()); +} + +static std::string tm2str(const std::tm *tm, const char *fmt) { -#ifdef WIN32 - SYSTEMTIME st; - // Retrieves the current system date and time. The system time is expressed in Coordinated Universal Time (UTC). - ::GetSystemTime(&st); - std::tm tm; - tm.tm_sec = st.wSecond; - tm.tm_min = st.wMinute; - tm.tm_hour = st.wHour; - tm.tm_mday = st.wDay; - tm.tm_mon = st.wMonth - 1; - tm.tm_year = st.wYear - 1900; - tm.tm_isdst = -1; - return _mkgmtime(&tm); -#else - // time() returns the time as the number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). - return time(nullptr); -#endif + std::stringstream ss; + ss << put_time(tm, fmt); + return ss.str(); +} + +std::string time2str(const time_t &t, TimeZone zone, const char *fmt) +{ + std::string ret; + + switch (zone) { + case TimeZone::local: ret = tm2str(std::localtime(&t), fmt); break; + case TimeZone::utc: ret = tm2str(std::gmtime(&t), fmt) + " UTC"; break; + } + + return ret; } }; // namespace Utils diff --git a/src/libslic3r/Time.hpp b/src/libslic3r/Time.hpp new file mode 100644 index 000000000..b314e47f7 --- /dev/null +++ b/src/libslic3r/Time.hpp @@ -0,0 +1,47 @@ +#ifndef slic3r_Utils_Time_hpp_ +#define slic3r_Utils_Time_hpp_ + +#include <string> +#include <ctime> + +namespace Slic3r { +namespace Utils { + +// Utilities to convert an UTC time_t to/from an ISO8601 time format, +// useful for putting timestamps into file and directory names. +// Returns (time_t)-1 on error. +time_t parse_time_ISO8601Z(const std::string &s); +std::string format_time_ISO8601Z(time_t time); + +// Format the date and time from an UTC time according to the active locales and a local time zone. +// TODO: make sure time2str is a suitable replacement +std::string format_local_date_time(time_t time); + +// There is no gmtime() on windows. +time_t get_current_time_utc(); + +const constexpr char *const SLIC3R_TIME_FMT = "%Y-%m-%d at %T"; + +enum class TimeZone { local, utc }; + +std::string time2str(const time_t &t, TimeZone zone, const char *fmt = SLIC3R_TIME_FMT); + +inline std::string current_time2str(TimeZone zone, const char *fmt = SLIC3R_TIME_FMT) +{ + return time2str(get_current_time_utc(), zone, fmt); +} + +inline std::string current_local_time2str(const char * fmt = SLIC3R_TIME_FMT) +{ + return current_time2str(TimeZone::local, fmt); +} + +inline std::string current_utc_time2str(const char * fmt = SLIC3R_TIME_FMT) +{ + return current_time2str(TimeZone::utc, fmt); +} + +}; // namespace Utils +}; // namespace Slic3r + +#endif /* slic3r_Utils_Time_hpp_ */ diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 2b1fdb241..5d847573d 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -87,11 +87,9 @@ namespace PerlUtils { std::string string_printf(const char *format, ...); -// Timestamp formatted for header_slic3r_generated(). -extern std::string timestamp_str(); // Standard "generated by Slic3r version xxx timestamp xxx" header string, // to be placed at the top of Slic3r generated files. -inline std::string header_slic3r_generated() { return std::string("generated by " SLIC3R_APP_NAME " " SLIC3R_VERSION " " ) + timestamp_str(); } +std::string header_slic3r_generated(); // getpid platform wrapper extern unsigned get_current_pid(); diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index e26ed3839..895efdb4d 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -6,6 +6,8 @@ #include <cstdarg> #include <stdio.h> +#include "Time.hpp" + #ifdef WIN32 #include <windows.h> #include <psapi.h> @@ -29,7 +31,6 @@ #include <boost/locale.hpp> #include <boost/algorithm/string/predicate.hpp> -#include <boost/date_time/local_time/local_time.hpp> #include <boost/filesystem.hpp> #include <boost/filesystem/path.hpp> #include <boost/nowide/fstream.hpp> @@ -540,16 +541,9 @@ std::string string_printf(const char *format, ...) return res; } - -std::string timestamp_str() +std::string header_slic3r_generated() { - const auto now = boost::posix_time::second_clock::local_time(); - char buf[2048]; - sprintf(buf, "on %04d-%02d-%02d at %02d:%02d:%02d", - // Local date in an ANSII format. - int(now.date().year()), int(now.date().month()), int(now.date().day()), - int(now.time_of_day().hours()), int(now.time_of_day().minutes()), int(now.time_of_day().seconds())); - return buf; + return std::string("generated by " SLIC3R_APP_NAME " " SLIC3R_VERSION " on " ) + Utils::current_utc_time2str(); } unsigned get_current_pid() diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index e51415d53..161e1a1ff 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -148,8 +148,6 @@ set(SLIC3R_GUI_SOURCES Utils/Bonjour.hpp Utils/PresetUpdater.cpp Utils/PresetUpdater.hpp - Utils/Time.cpp - Utils/Time.hpp Utils/UndoRedo.cpp Utils/UndoRedo.hpp Utils/HexFile.cpp diff --git a/src/slic3r/Config/Snapshot.cpp b/src/slic3r/Config/Snapshot.cpp index 2aebd0c72..622b31a17 100644 --- a/src/slic3r/Config/Snapshot.cpp +++ b/src/slic3r/Config/Snapshot.cpp @@ -1,7 +1,6 @@ #include "Snapshot.hpp" #include "../GUI/AppConfig.hpp" #include "../GUI/PresetBundle.hpp" -#include "../Utils/Time.hpp" #include <time.h> @@ -13,6 +12,7 @@ #include <boost/property_tree/ptree.hpp> #include "libslic3r/libslic3r.h" +#include "libslic3r/Time.hpp" #include "libslic3r/Config.hpp" #include "libslic3r/FileParserError.hpp" #include "libslic3r/Utils.hpp" diff --git a/src/slic3r/GUI/ConfigSnapshotDialog.cpp b/src/slic3r/GUI/ConfigSnapshotDialog.cpp index 59ed38412..836a0a4d3 100644 --- a/src/slic3r/GUI/ConfigSnapshotDialog.cpp +++ b/src/slic3r/GUI/ConfigSnapshotDialog.cpp @@ -2,9 +2,9 @@ #include "I18N.hpp" #include "../Config/Snapshot.hpp" -#include "../Utils/Time.hpp" #include "libslic3r/Utils.hpp" +#include "libslic3r/Time.hpp" #include "GUI_App.hpp" #include "wxExtensions.hpp" diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 803510f80..3075d11ed 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1135,7 +1135,8 @@ void Sidebar::show_sliced_info_sizer(const bool show) p->sliced_info->SetTextAndShow(siMateril_unit, info_text, new_label); p->sliced_info->SetTextAndShow(siCost, "N/A"/*wxString::Format("%.2f", ps.total_cost)*/); - p->sliced_info->SetTextAndShow(siEstimatedTime, ps.estimated_print_time, _(L("Estimated printing time")) + " :"); + wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : get_time_dhms(float(ps.estimated_print_time)); + p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _(L("Estimated printing time")) + " :"); // Hide non-SLA sliced info parameters p->sliced_info->SetTextAndShow(siFilament_m, "N/A"); diff --git a/src/slic3r/Utils/Time.hpp b/src/slic3r/Utils/Time.hpp deleted file mode 100644 index 6a1aefa18..000000000 --- a/src/slic3r/Utils/Time.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef slic3r_Utils_Time_hpp_ -#define slic3r_Utils_Time_hpp_ - -#include <string> -#include <ctime> - -namespace Slic3r { -namespace Utils { - -// Utilities to convert an UTC time_t to/from an ISO8601 time format, -// useful for putting timestamps into file and directory names. -// Returns (time_t)-1 on error. -extern time_t parse_time_ISO8601Z(const std::string &s); -extern std::string format_time_ISO8601Z(time_t time); - -// Format the date and time from an UTC time according to the active locales and a local time zone. -extern std::string format_local_date_time(time_t time); - -// There is no gmtime() on windows. -extern time_t get_current_time_utc(); - -}; // namespace Utils -}; // namespace Slic3r - -#endif /* slic3r_Utils_Time_hpp_ */ |