From dfcb502ef46df5f18aa64c7e3ca6a06fb0ca1e05 Mon Sep 17 00:00:00 2001
From: Enrico Turri <enricoturri@seznam.cz>
Date: Mon, 8 Jan 2018 12:17:39 +0100
Subject: [PATCH 1/3] GCodeTimeEstimator - Fixed square roots of negative
 numbers

---
 xs/src/libslic3r/GCodeTimeEstimator.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp
index 2edbfeac5..b65ff555b 100644
--- a/xs/src/libslic3r/GCodeTimeEstimator.cpp
+++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp
@@ -56,7 +56,9 @@ namespace Slic3r {
 
     float GCodeTimeEstimator::Block::Trapezoid::speed_from_distance(float initial_feedrate, float distance, float acceleration)
     {
-        return ::sqrt(sqr(initial_feedrate) + 2.0f * acceleration * distance);
+        // to avoid invalid negative numbers due to numerical imprecision 
+        float value = std::max(0.0f, sqr(initial_feedrate) + 2.0f * acceleration * distance);
+        return ::sqrt(value);
     }
 
     float GCodeTimeEstimator::Block::move_length() const
@@ -122,7 +124,9 @@ namespace Slic3r {
 
     float GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance)
     {
-        return ::sqrt(sqr(target_velocity) - 2.0f * acceleration * distance);
+        // to avoid invalid negative numbers due to numerical imprecision 
+        float value = std::max(0.0f, sqr(target_velocity) - 2.0f * acceleration * distance);
+        return ::sqrt(value);
     }
 
     float GCodeTimeEstimator::Block::estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration)

From aeca5def00f14e5ae2dc12264e57ab04965d83d9 Mon Sep 17 00:00:00 2001
From: Enrico Turri <enricoturri@seznam.cz>
Date: Mon, 8 Jan 2018 12:27:18 +0100
Subject: [PATCH 2/3] GCodeTimeEstimator - Added credits for CuraEngine

---
 xs/src/libslic3r/GCodeTimeEstimator.hpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp
index 9e429462e..63dd0a6c6 100644
--- a/xs/src/libslic3r/GCodeTimeEstimator.hpp
+++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp
@@ -7,6 +7,11 @@
 
 namespace Slic3r {
 
+    //
+    // Some of the algorithms used by class GCodeTimeEstimator were inpired by
+    // Cura Engine's class TimeEstimateCalculator
+    // https://github.com/Ultimaker/CuraEngine/blob/master/src/timeEstimate.h
+    //
     class GCodeTimeEstimator
     {
     public:

From e94491ee8c3a652ed16158d87f55543d30ac1f6f Mon Sep 17 00:00:00 2001
From: Enrico Turri <enricoturri@seznam.cz>
Date: Mon, 8 Jan 2018 13:23:54 +0100
Subject: [PATCH 3/3] GCodeTimeEstimator - Fixed _simulate_st_synchronize()

---
 xs/src/libslic3r/GCodeTimeEstimator.cpp | 16 +++++++++++++---
 xs/src/libslic3r/GCodeTimeEstimator.hpp |  1 +
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp
index b65ff555b..22821a708 100644
--- a/xs/src/libslic3r/GCodeTimeEstimator.cpp
+++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp
@@ -153,6 +153,9 @@ namespace Slic3r {
             [this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
         { this->_process_gcode_line(reader, line); });
 
+        _calculate_time();
+
+        _reset_blocks();
         _reset();
     }
 
@@ -163,6 +166,7 @@ namespace Slic3r {
         _parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2));
         _calculate_time();
 
+        _reset_blocks();
         _reset();
     }
 
@@ -176,6 +180,7 @@ namespace Slic3r {
             _parser.parse_line(line, action);
         _calculate_time();
 
+        _reset_blocks();
         _reset();
     }
 
@@ -203,6 +208,7 @@ namespace Slic3r {
     {
         PROFILE_FUNC();
         _calculate_time();
+        _reset_blocks();
         _reset();
     }
 
@@ -387,6 +393,7 @@ namespace Slic3r {
     void GCodeTimeEstimator::reset()
     {
         _time = 0.0f;
+        _reset_blocks();
         _reset();
     }
 
@@ -416,8 +423,6 @@ namespace Slic3r {
 
     void GCodeTimeEstimator::_reset()
     {
-        _blocks.clear();
-
         _curr.reset();
         _prev.reset();
 
@@ -428,6 +433,11 @@ namespace Slic3r {
         set_additional_time(0.0f);
     }
 
+    void GCodeTimeEstimator::_reset_blocks()
+    {
+        _blocks.clear();
+    }
+
     void GCodeTimeEstimator::_calculate_time()
     {
         _forward_pass();
@@ -954,7 +964,7 @@ namespace Slic3r {
     void GCodeTimeEstimator::_simulate_st_synchronize()
     {
         _calculate_time();
-        _reset();
+        _reset_blocks();
     }
 
     void GCodeTimeEstimator::_forward_pass()
diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp
index 63dd0a6c6..fb41a2753 100644
--- a/xs/src/libslic3r/GCodeTimeEstimator.hpp
+++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp
@@ -246,6 +246,7 @@ namespace Slic3r {
 
     private:
         void _reset();
+        void _reset_blocks();
 
         // Calculates the time estimate
         void _calculate_time();