diff options
Diffstat (limited to 'src/libslic3r/GCode/WipeTower.hpp')
-rw-r--r-- | src/libslic3r/GCode/WipeTower.hpp | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp new file mode 100644 index 000000000..5cbbc1ca9 --- /dev/null +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -0,0 +1,167 @@ +#ifndef slic3r_WipeTower_hpp_ +#define slic3r_WipeTower_hpp_ + +#include <utility> +#include <string> +#include <vector> + +namespace Slic3r +{ + +// A pure virtual WipeTower definition. +class WipeTower +{ +public: + // Internal point class, to make the wipe tower independent from other slic3r modules. + // This is important for Prusa Research as we want to build the wipe tower post-processor independently from slic3r. + struct xy + { + xy(float x = 0.f, float y = 0.f) : x(x), y(y) {} + xy(const xy& pos,float xp,float yp) : x(pos.x+xp), y(pos.y+yp) {} + xy operator+(const xy &rhs) const { xy out(*this); out.x += rhs.x; out.y += rhs.y; return out; } + xy operator-(const xy &rhs) const { xy out(*this); out.x -= rhs.x; out.y -= rhs.y; return out; } + xy& operator+=(const xy &rhs) { x += rhs.x; y += rhs.y; return *this; } + xy& operator-=(const xy &rhs) { x -= rhs.x; y -= rhs.y; return *this; } + bool operator==(const xy &rhs) const { return x == rhs.x && y == rhs.y; } + bool operator!=(const xy &rhs) const { return x != rhs.x || y != rhs.y; } + + // Rotate the point around center of the wipe tower about given angle (in degrees) + xy rotate(float width, float depth, float angle) const { + xy out(0,0); + float temp_x = x - width / 2.f; + float temp_y = y - depth / 2.f; + angle *= float(M_PI/180.); + out.x += temp_x * cos(angle) - temp_y * sin(angle) + width / 2.f; + out.y += temp_x * sin(angle) + temp_y * cos(angle) + depth / 2.f; + return out; + } + + // Rotate the point around origin about given angle in degrees + void rotate(float angle) { + float temp_x = x * cos(angle) - y * sin(angle); + y = x * sin(angle) + y * cos(angle); + x = temp_x; + } + + void translate(const xy& vect) { + x += vect.x; + y += vect.y; + } + + float x; + float y; + }; + + WipeTower() {} + virtual ~WipeTower() {} + + // Return the wipe tower position. + virtual const xy& position() const = 0; + + // Return the wipe tower width. + virtual float width() const = 0; + + // The wipe tower is finished, there should be no more tool changes or wipe tower prints. + virtual bool finished() const = 0; + + // Switch to a next layer. + virtual void set_layer( + // Print height of this layer. + float print_z, + // Layer height, used to calculate extrusion the rate. + float layer_height, + // Maximum number of tool changes on this layer or the layers below. + size_t max_tool_changes, + // Is this the first layer of the print? In that case print the brim first. + bool is_first_layer, + // Is this the last layer of the wipe tower? + bool is_last_layer) = 0; + + enum Purpose { + PURPOSE_MOVE_TO_TOWER, + PURPOSE_EXTRUDE, + PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE, + }; + + // Extrusion path of the wipe tower, for 3D preview of the generated tool paths. + struct Extrusion + { + Extrusion(const xy &pos, float width, unsigned int tool) : pos(pos), width(width), tool(tool) {} + // End position of this extrusion. + xy pos; + // Width of a squished extrusion, corrected for the roundings of the squished extrusions. + // This is left zero if it is a travel move. + float width; + // Current extruder index. + unsigned int tool; + }; + + struct ToolChangeResult + { + // Print heigh of this tool change. + float print_z; + float layer_height; + // G-code section to be directly included into the output G-code. + std::string gcode; + // For path preview. + std::vector<Extrusion> extrusions; + // Initial position, at which the wipe tower starts its action. + // At this position the extruder is loaded and there is no Z-hop applied. + xy start_pos; + // Last point, at which the normal G-code generator of Slic3r shall continue. + // At this position the extruder is loaded and there is no Z-hop applied. + xy end_pos; + // Time elapsed over this tool change. + // This is useful not only for the print time estimation, but also for the control of layer cooling. + float elapsed_time; + + // Is this a priming extrusion? (If so, the wipe tower rotation & translation will not be applied later) + bool priming; + + // Sum the total length of the extrusion. + float total_extrusion_length_in_plane() { + float e_length = 0.f; + for (size_t i = 1; i < this->extrusions.size(); ++ i) { + const Extrusion &e = this->extrusions[i]; + if (e.width > 0) { + xy v = e.pos - (&e - 1)->pos; + e_length += sqrt(v.x*v.x+v.y*v.y); + } + } + return e_length; + } + }; + + // Returns gcode to prime the nozzles at the front edge of the print bed. + virtual ToolChangeResult prime( + // print_z of the first layer. + float first_layer_height, + // Extruder indices, in the order to be primed. The last extruder will later print the wipe tower brim, print brim and the object. + const std::vector<unsigned int> &tools, + // If true, the last priming are will be the same as the other priming areas, and the rest of the wipe will be performed inside the wipe tower. + // If false, the last priming are will be large enough to wipe the last extruder sufficiently. + bool last_wipe_inside_wipe_tower) = 0; + + // Returns gcode for toolchange and the end position. + // if new_tool == -1, just unload the current filament over the wipe tower. + virtual ToolChangeResult tool_change(unsigned int new_tool, bool last_in_layer) = 0; + + // Close the current wipe tower layer with a perimeter and possibly fill the unfilled space with a zig-zag. + // Call this method only if layer_finished() is false. + virtual ToolChangeResult finish_layer() = 0; + + // Is the current layer finished? A layer is finished if either the wipe tower is finished, or + // the wipe tower has been completely covered by the tool change extrusions, + // or the rest of the tower has been filled by a sparse infill with the finish_layer() method. + virtual bool layer_finished() const = 0; + + // Returns used filament length per extruder: + virtual std::vector<float> get_used_filament() const = 0; + + // Returns total number of toolchanges: + virtual int get_number_of_toolchanges() const = 0; +}; + +}; // namespace Slic3r + +#endif /* slic3r_WipeTower_hpp_ */ |