Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2019-09-12 11:19:09 +0300
committerbubnikv <bubnikv@gmail.com>2019-09-12 11:19:09 +0300
commitb4f2df6a98369b0de813c237c564c4cffbedf4ea (patch)
tree1279340beec33e39adb05ae3020a25d7126ded04 /src
parent22ab0220889ca72dc82b478be3e0c62bca4cfba6 (diff)
parent6f4fff1b29476e70a327f8c0c2ca2e16dc6b6a34 (diff)
Merge remote-tracking branch 'remotes/origin/master' into dev
Diffstat (limited to 'src')
-rw-r--r--src/admesh/stlinit.cpp4
-rw-r--r--src/libslic3r/CMakeLists.txt2
-rw-r--r--src/libslic3r/GCode/Analyzer.cpp5
-rw-r--r--src/libslic3r/SLA/SLARaster.hpp13
-rw-r--r--src/libslic3r/SLA/SLARasterWriter.cpp107
-rw-r--r--src/libslic3r/SLA/SLARasterWriter.hpp109
-rw-r--r--src/libslic3r/SLAPrint.cpp76
-rw-r--r--src/libslic3r/SLAPrint.hpp14
-rw-r--r--src/libslic3r/Time.cpp (renamed from src/slic3r/Utils/Time.cpp)68
-rw-r--r--src/libslic3r/Time.hpp47
-rw-r--r--src/libslic3r/Utils.hpp4
-rw-r--r--src/libslic3r/utils.cpp14
-rw-r--r--src/slic3r/CMakeLists.txt2
-rw-r--r--src/slic3r/Config/Snapshot.cpp2
-rw-r--r--src/slic3r/GUI/ConfigSnapshotDialog.cpp2
-rw-r--r--src/slic3r/GUI/Plater.cpp3
-rw-r--r--src/slic3r/Utils/Time.hpp25
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 &param : 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_ */