From a782424d5f4ab4e34e4291af8cee965b2ad23848 Mon Sep 17 00:00:00 2001
From: Lukas Matena <lukasmatena@seznam.cz>
Date: Tue, 20 Mar 2018 15:07:18 +0100
Subject: [PATCH] Wipe tower generator connected to purging volumes from the
 configuration layer

---
 xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp |  8 +--
 xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp | 63 ++-------------------
 xs/src/libslic3r/Print.cpp                  |  4 +-
 xs/src/slic3r/GUI/WipeTowerDialog.hpp       |  5 --
 4 files changed, 13 insertions(+), 67 deletions(-)

diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
index 59fa7dced..2010b7ae7 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
@@ -514,7 +514,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
         toolchange_Load(writer, cleaning_box); // Prime the tool.
         if (idx_tool + 1 == tools.size()) {
             // Last tool should not be unloaded, but it should be wiped enough to become of a pure color.
-            toolchange_Wipe(writer, cleaning_box, m_par.wipe_volumes[tools[idx_tool-1]][tool]);
+            toolchange_Wipe(writer, cleaning_box, wipe_volumes[tools[idx_tool-1]][tool]);
         } else {
             // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
             //writer.travel(writer.x(), writer.y() + m_perimeter_width, 7200);
@@ -566,7 +566,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
 	{
 		for (const auto &b : m_layer_info->tool_changes)
 			if ( b.new_tool == tool ) {
-				wipe_volume = m_par.wipe_volumes[b.old_tool][b.new_tool];
+				wipe_volume = wipe_volumes[b.old_tool][b.new_tool];
 				if (tool == m_layer_info->tool_changes.back().new_tool)
 					last_change_in_layer = true;
 				wipe_area = b.required_depth * m_layer_info->extra_spacing;
@@ -1100,7 +1100,7 @@ void WipeTowerPrusaMM::plan_toolchange(float z_par, float layer_height_par, unsi
     float ramming_depth = depth;
     length_to_extrude = width*((length_to_extrude / width)-int(length_to_extrude / width)) - width;
     float first_wipe_line = -length_to_extrude;
-    length_to_extrude += volume_to_length(m_par.wipe_volumes[old_tool][new_tool], m_line_width, layer_height_par);
+    length_to_extrude += volume_to_length(wipe_volumes[old_tool][new_tool], m_line_width, layer_height_par);
     length_to_extrude = std::max(length_to_extrude,0.f);
 
 	depth += (int(length_to_extrude / width) + 1) * m_line_width;
@@ -1146,7 +1146,7 @@ void WipeTowerPrusaMM::save_on_last_wipe()
 
         float width = m_wipe_tower_width - 3*m_perimeter_width; // width we draw into
         float length_to_save = 2*(m_wipe_tower_width+m_wipe_tower_depth) + (!layer_finished() ? finish_layer().total_extrusion_length_in_plane() : 0.f);
-        float length_to_wipe = volume_to_length(m_par.wipe_volumes[m_layer_info->tool_changes.back().old_tool][m_layer_info->tool_changes.back().new_tool],
+        float length_to_wipe = volume_to_length(wipe_volumes[m_layer_info->tool_changes.back().old_tool][m_layer_info->tool_changes.back().new_tool],
                               m_line_width,m_layer_info->height)  - m_layer_info->tool_changes.back().first_wipe_line - length_to_save;
 
         length_to_wipe = std::max(length_to_wipe,0.f);
diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
index 8cfc5872c..acdcef8f2 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
@@ -31,59 +31,6 @@ namespace PrusaMultiMaterial {
 
 
 
-// Operator overload to output std::pairs
-template <typename T>
-std::ostream& operator<<(std::ostream& stream,const std::pair<T,T>& pair) {
-    return stream << pair.first << " " << pair.second;
-}
-
-// Operator overload to output elements of a vector to std::ofstream easily:
-template <typename T>
-std::ostream& operator<<(std::ostream& stream,const std::vector<T>& vect) {
-    for (const auto& element : vect)
-        stream << element << " ";
-    return stream;
-}
-
-// Operator overload to input elements of a vector from std::ifstream easily (reads until a fail)
-template <typename T>
-std::istream& operator>>(std::istream& stream, std::vector<T>& vect) {
-    vect.clear();
-    T value{};
-    bool we_read_something = false;
-    while (stream >> value) {
-        vect.push_back(value);
-        we_read_something = true;
-    }
-    if (!stream.eof() && we_read_something) { // if this is not eof, we might be at separator - let's get rid of it
-        stream.clear();     // if we failed on very first line or reached eof, return stream in good() state
-        stream.get();       // get() whatever we are stuck at
-    }
-    return stream;
-}
-
-
-// This struct is used to store parameters and to pass it to wipe tower generator
-struct WipeTowerParameters {
-    WipeTowerParameters() {  }           // create new empty object
-    WipeTowerParameters(const std::string& init_data) { // create object and initialize from std::string
-        set_defaults();
-    }
-    
-    void set_defaults() {
-        sampling = 0.25f;
-        wipe_volumes = {{  0.f, 60.f, 60.f, 60.f},
-                        { 60.f,  0.f, 60.f, 60.f},
-                        { 60.f, 60.f,  0.f, 60.f},
-                        { 60.f, 60.f, 60.f,  0.f}};
-        filament_wipe_volumes = {{30.f,30.f},{30.f,30.f},{30.f,30.f},{30.f,30.f}};
-    }
-    
-    float sampling = 0.25f; // this does not quite work yet, keep it fixed to 0.25f
-    std::vector<std::vector<float>> wipe_volumes;
-    std::vector<std::pair<int,int>> filament_wipe_volumes;
-};
-
 
 class WipeTowerPrusaMM : public WipeTower
 {
@@ -110,7 +57,7 @@ public:
 	// width		-- width of wipe tower in mm ( default 60 mm - leave as it is )
 	// wipe_area	-- space available for one toolchange in mm
 	WipeTowerPrusaMM(float x, float y, float width, float wipe_area, float rotation_angle, float cooling_tube_retraction,
-                     float cooling_tube_length, float parking_pos_retraction, float bridging, const std::string& parameters,
+                     float cooling_tube_length, float parking_pos_retraction, float bridging, const std::vector<float>& wiping_matrix,
                      unsigned int initial_tool) :
 		m_wipe_tower_pos(x, y),
 		m_wipe_tower_width(width),
@@ -123,9 +70,11 @@ public:
         m_cooling_tube_length(cooling_tube_length),
         m_parking_pos_retraction(parking_pos_retraction),
 		m_current_tool(initial_tool),
-        m_par(parameters) 
+        m_bridging(bridging)
  	{
-        m_bridging = bridging;
+        const unsigned int number_of_extruders = int(sqrt(wiping_matrix.size())+WT_EPSILON);
+        for (unsigned int i = 0; i<number_of_extruders; ++i)
+            wipe_volumes.push_back(std::vector<float>(wiping_matrix.begin()+i*number_of_extruders,wiping_matrix.begin()+(i+1)*number_of_extruders));
         
 		for (size_t i = 0; i < 4; ++ i) {
 			// Extruder specific parameters.
@@ -301,7 +250,7 @@ private:
 	// A fill-in direction (positive Y, negative Y) alternates with each layer.
 	wipe_shape   	m_current_shape = SHAPE_NORMAL;
 	unsigned int 	m_current_tool  = 0;
-    WipeTowerParameters m_par;
+    std::vector<std::vector<float>> wipe_volumes;
 
 	float m_depth_traversed = 0.f; // Current y position at the wipe tower.
 	// How much to wipe the 1st extruder over the wipe tower at the 1st layer
diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp
index 0167b8ba7..acff4492a 100644
--- a/xs/src/libslic3r/Print.cpp
+++ b/xs/src/libslic3r/Print.cpp
@@ -202,6 +202,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
             || opt_key == "wipe_tower_per_color_wipe"
             || opt_key == "wipe_tower_rotation_angle"
             || opt_key == "wipe_tower_bridging"
+            || opt_key == "wiping_volumes_matrix"
             || opt_key == "z_offset") {
             steps.emplace_back(psWipeTower);
         } else if (
@@ -1043,7 +1044,8 @@ void Print::_make_wipe_tower()
         float(this->config.wipe_tower_rotation_angle.value), float(this->config.cooling_tube_retraction.value),
         float(this->config.cooling_tube_length.value), float(this->config.parking_pos_retraction.value),
         float(this->config.wipe_tower_bridging),
-        /*this->config.wipe_tower_advanced.value*/std::string(""),m_tool_ordering.first_extruder());
+        std::vector<float>((this->config.wiping_volumes_matrix.values).begin(),(this->config.wiping_volumes_matrix.values).end()),
+        m_tool_ordering.first_extruder());
     
     //wipe_tower.set_retract();
     //wipe_tower.set_zhop();
diff --git a/xs/src/slic3r/GUI/WipeTowerDialog.hpp b/xs/src/slic3r/GUI/WipeTowerDialog.hpp
index 0adefe5f2..54ae9596d 100644
--- a/xs/src/slic3r/GUI/WipeTowerDialog.hpp
+++ b/xs/src/slic3r/GUI/WipeTowerDialog.hpp
@@ -5,16 +5,11 @@
 #include <wx/stattext.h>
 #include <wx/textctrl.h>
 #include <wx/checkbox.h>
-#include <wx/choicdlg.h>
-#include <wx/notebook.h>
 #include <wx/msgdlg.h>
 
-#include "../../libslic3r/GCode/WipeTowerPrusaMM.hpp"
 #include "RammingChart.hpp"
 
 
-std::ostream& operator<<(std::ostream& str,Slic3r::WipeTowerParameters& par);
-
 class RammingPanel : public wxPanel {
 public:
     RammingPanel(wxWindow* parent);