2017-05-16 11:45:28 +00:00
|
|
|
#ifndef WipeTowerPrusaMM_hpp_
|
|
|
|
#define WipeTowerPrusaMM_hpp_
|
|
|
|
|
|
|
|
#include <algorithm>
|
2017-05-16 14:02:52 +00:00
|
|
|
#include <cmath>
|
2017-05-16 11:45:28 +00:00
|
|
|
#include <string>
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
#include "WipeTower.hpp"
|
|
|
|
|
2017-12-07 10:59:14 +00:00
|
|
|
// Following is used to calculate extrusion flow - should be taken from config in future
|
|
|
|
constexpr float Filament_Diameter = 1.75f; // filament diameter in mm
|
|
|
|
constexpr float Nozzle_Diameter = 0.4f; // nozzle diameter in mm
|
|
|
|
// desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
|
|
|
|
constexpr float Width_To_Nozzle_Ratio = 1.f;
|
|
|
|
// m_perimeter_width was hardcoded until now as 0.5 (for 0.4 nozzle and 0.2 layer height)
|
|
|
|
// Konst = 1.25 implies same result
|
|
|
|
constexpr float Konst = 1.25f;
|
|
|
|
constexpr float m_perimeter_width = Nozzle_Diameter * Width_To_Nozzle_Ratio * Konst;
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-11-30 11:08:22 +00:00
|
|
|
|
2017-05-16 11:45:28 +00:00
|
|
|
namespace Slic3r
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace PrusaMultiMaterial {
|
|
|
|
class Writer;
|
|
|
|
};
|
|
|
|
|
|
|
|
class WipeTowerPrusaMM : public WipeTower
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum material_type
|
|
|
|
{
|
|
|
|
INVALID = -1,
|
|
|
|
PLA = 0, // E:210C B:55C
|
|
|
|
ABS = 1, // E:255C B:100C
|
|
|
|
PET = 2, // E:240C B:90C
|
|
|
|
HIPS = 3, // E:220C B:100C
|
|
|
|
FLEX = 4, // E:245C B:80C
|
|
|
|
SCAFF = 5, // E:215C B:55C
|
|
|
|
EDGE = 6, // E:240C B:80C
|
|
|
|
NGEN = 7, // E:230C B:80C
|
|
|
|
PVA = 8 // E:210C B:80C
|
|
|
|
};
|
|
|
|
|
|
|
|
// Parse material name into material_type.
|
|
|
|
static material_type parse_material(const char *name);
|
|
|
|
|
|
|
|
// x -- x coordinates of wipe tower in mm ( left bottom corner )
|
|
|
|
// y -- y coordinates of wipe tower in mm ( left bottom corner )
|
|
|
|
// width -- width of wipe tower in mm ( default 60 mm - leave as it is )
|
|
|
|
// wipe_area -- space available for one toolchange in mm
|
2017-11-30 11:08:22 +00:00
|
|
|
WipeTowerPrusaMM(float x, float y, float width, float wipe_area, float rotation_angle, unsigned int initial_tool) :
|
2017-05-16 11:45:28 +00:00
|
|
|
m_wipe_tower_pos(x, y),
|
|
|
|
m_wipe_tower_width(width),
|
|
|
|
m_wipe_area(wipe_area),
|
2017-11-30 11:08:22 +00:00
|
|
|
m_wipe_tower_rotation_angle(rotation_angle),
|
2017-05-25 20:27:53 +00:00
|
|
|
m_z_pos(0.f),
|
|
|
|
m_current_tool(initial_tool)
|
|
|
|
{
|
2017-05-16 11:45:28 +00:00
|
|
|
for (size_t i = 0; i < 4; ++ i) {
|
|
|
|
// Extruder specific parameters.
|
|
|
|
m_material[i] = PLA;
|
|
|
|
m_temperature[i] = 0;
|
|
|
|
m_first_layer_temperature[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
2017-05-25 20:27:53 +00:00
|
|
|
|
2017-05-16 11:45:28 +00:00
|
|
|
virtual ~WipeTowerPrusaMM() {}
|
|
|
|
|
|
|
|
// _retract - retract value in mm
|
|
|
|
void set_retract(float retract) { m_retract = retract; }
|
|
|
|
|
|
|
|
// _zHop - z hop value in mm
|
|
|
|
void set_zhop(float zhop) { m_zhop = zhop; }
|
2017-12-07 10:59:14 +00:00
|
|
|
|
2017-05-16 11:45:28 +00:00
|
|
|
// Set the extruder properties.
|
|
|
|
void set_extruder(size_t idx, material_type material, int temp, int first_layer_temp)
|
|
|
|
{
|
|
|
|
m_material[idx] = material;
|
|
|
|
m_temperature[idx] = temp;
|
|
|
|
m_first_layer_temperature[idx] = first_layer_temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 waste tower?
|
|
|
|
bool is_last_layer)
|
|
|
|
{
|
2017-12-05 10:25:38 +00:00
|
|
|
if (is_first_layer)
|
|
|
|
m_wipe_tower_depth = m_wipe_area * max_tool_changes; // tower depth (y-range) of the bottom
|
|
|
|
|
2017-05-16 11:45:28 +00:00
|
|
|
m_z_pos = print_z;
|
2017-05-25 20:27:53 +00:00
|
|
|
m_layer_height = layer_height;
|
2017-05-16 11:45:28 +00:00
|
|
|
m_max_color_changes = max_tool_changes;
|
|
|
|
m_is_first_layer = is_first_layer;
|
|
|
|
m_is_last_layer = is_last_layer;
|
2017-05-17 08:42:39 +00:00
|
|
|
// Start counting the color changes from zero. Special case: -1 - extrude a brim first.
|
2017-05-17 14:45:37 +00:00
|
|
|
m_idx_tool_change_in_layer = is_first_layer ? (unsigned int)(-1) : 0;
|
2017-05-16 11:45:28 +00:00
|
|
|
m_current_wipe_start_y = 0.f;
|
2017-05-17 14:45:37 +00:00
|
|
|
m_current_shape = (! is_first_layer && m_current_shape == SHAPE_NORMAL) ? SHAPE_REVERSED : SHAPE_NORMAL;
|
2017-05-18 14:53:19 +00:00
|
|
|
++ m_num_layer_changes;
|
2017-06-08 10:10:34 +00:00
|
|
|
// Extrusion rate for an extrusion aka perimeter width 0.35mm.
|
2017-08-28 12:57:00 +00:00
|
|
|
// Clamp the extrusion height to a 0.2mm layer height, independent of the nozzle diameter.
|
|
|
|
// m_extrusion_flow = std::min(0.2f, layer_height) * 0.145f;
|
|
|
|
// Use a strictly
|
2017-12-07 10:59:14 +00:00
|
|
|
//m_extrusion_flow = layer_height * 0.145f;
|
|
|
|
|
|
|
|
// Calculates extrusion flow from desired line width, nozzle diameter, filament diameter and layer_height
|
|
|
|
m_extrusion_flow = 4.f * layer_height * ( Width_To_Nozzle_Ratio * Nozzle_Diameter - layer_height * (1-M_PI/4.f)) /
|
|
|
|
(M_PI * pow(Filament_Diameter,2.f));
|
2017-05-16 11:45:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the wipe tower position.
|
2017-05-25 20:27:53 +00:00
|
|
|
virtual const xy& position() const { return m_wipe_tower_pos; }
|
2017-05-19 17:24:21 +00:00
|
|
|
// Return the wipe tower width.
|
2017-05-25 20:27:53 +00:00
|
|
|
virtual float width() const { return m_wipe_tower_width; }
|
2017-05-16 11:45:28 +00:00
|
|
|
// The wipe tower is finished, there should be no more tool changes or wipe tower prints.
|
2017-05-25 20:27:53 +00:00
|
|
|
virtual bool finished() const { return m_max_color_changes == 0; }
|
2017-05-16 11:45:28 +00:00
|
|
|
|
2017-09-01 15:30:18 +00:00
|
|
|
// Returns gcode to prime the nozzles at the front edge of the print bed.
|
2017-09-12 13:55:38 +00:00
|
|
|
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.
|
|
|
|
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,
|
|
|
|
// May be used by a stand alone post processor.
|
|
|
|
Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE);
|
2017-09-01 15:30:18 +00:00
|
|
|
|
2017-05-17 08:42:39 +00:00
|
|
|
// Returns gcode for a toolchange and a final print head position.
|
|
|
|
// On the first layer, extrude a brim around the future wipe tower first.
|
2017-09-01 15:30:18 +00:00
|
|
|
virtual ToolChangeResult tool_change(unsigned int new_tool, bool last_in_layer, Purpose purpose);
|
2017-05-16 11:45:28 +00:00
|
|
|
|
|
|
|
// Close the current wipe tower layer with a perimeter and possibly fill the unfilled space with a zig-zag.
|
2017-05-17 14:45:37 +00:00
|
|
|
// Call this method only if layer_finished() is false.
|
2017-05-25 20:27:53 +00:00
|
|
|
virtual ToolChangeResult finish_layer(Purpose purpose);
|
2017-05-17 14:45:37 +00:00
|
|
|
|
|
|
|
// 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.
|
2017-05-25 20:27:53 +00:00
|
|
|
virtual bool layer_finished() const
|
2017-05-17 14:45:37 +00:00
|
|
|
{ return m_idx_tool_change_in_layer == m_max_color_changes; }
|
2017-05-16 11:45:28 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
WipeTowerPrusaMM();
|
|
|
|
|
2017-05-17 08:42:39 +00:00
|
|
|
// A fill-in direction (positive Y, negative Y) alternates with each layer.
|
2017-05-16 11:45:28 +00:00
|
|
|
enum wipe_shape
|
|
|
|
{
|
|
|
|
SHAPE_NORMAL = 1,
|
|
|
|
SHAPE_REVERSED = -1
|
|
|
|
};
|
|
|
|
|
|
|
|
// Left front corner of the wipe tower in mm.
|
2017-05-18 14:53:19 +00:00
|
|
|
xy m_wipe_tower_pos;
|
2017-05-16 11:45:28 +00:00
|
|
|
// Width of the wipe tower.
|
2017-05-18 14:53:19 +00:00
|
|
|
float m_wipe_tower_width;
|
2017-12-05 10:25:38 +00:00
|
|
|
// Depth of the wipe tower (wipe_area * max_color_changes at the base)
|
|
|
|
float m_wipe_tower_depth;
|
2017-05-16 11:45:28 +00:00
|
|
|
// Per color Y span.
|
2017-05-18 14:53:19 +00:00
|
|
|
float m_wipe_area;
|
2017-11-30 11:08:22 +00:00
|
|
|
// Wipe tower rotation angle in degrees (with respect to x axis
|
|
|
|
float m_wipe_tower_rotation_angle;
|
2017-05-16 11:45:28 +00:00
|
|
|
// Current Z position.
|
2017-05-18 14:53:19 +00:00
|
|
|
float m_z_pos = 0.f;
|
2017-05-25 20:27:53 +00:00
|
|
|
// Current layer height.
|
|
|
|
float m_layer_height = 0.f;
|
2017-05-16 11:45:28 +00:00
|
|
|
// Maximum number of color changes per layer.
|
2017-05-18 14:53:19 +00:00
|
|
|
size_t m_max_color_changes = 0;
|
2017-05-16 11:45:28 +00:00
|
|
|
// Is this the 1st layer of the print? If so, print the brim around the waste tower.
|
2017-05-18 14:53:19 +00:00
|
|
|
bool m_is_first_layer = false;
|
2017-05-16 11:45:28 +00:00
|
|
|
// Is this the last layer of this waste tower?
|
2017-05-18 14:53:19 +00:00
|
|
|
bool m_is_last_layer = false;
|
2017-05-16 11:45:28 +00:00
|
|
|
|
|
|
|
// G-code generator parameters.
|
2017-05-18 14:53:19 +00:00
|
|
|
float m_zhop = 0.5f;
|
|
|
|
float m_retract = 4.f;
|
2017-05-17 08:42:39 +00:00
|
|
|
// Width of an extrusion line, also a perimeter spacing for 100% infill.
|
2017-12-07 10:59:14 +00:00
|
|
|
float m_line_width = Nozzle_Diameter * Width_To_Nozzle_Ratio;
|
2017-12-05 10:25:38 +00:00
|
|
|
|
2017-05-17 08:42:39 +00:00
|
|
|
// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter.
|
2017-05-18 14:53:19 +00:00
|
|
|
float m_extrusion_flow = 0.029f;
|
2017-05-16 11:45:28 +00:00
|
|
|
|
|
|
|
// Extruder specific parameters.
|
|
|
|
material_type m_material[4];
|
|
|
|
int m_temperature[4];
|
|
|
|
int m_first_layer_temperature[4];
|
|
|
|
|
|
|
|
// State of the wiper tower generator.
|
|
|
|
// Layer change counter for the output statistics.
|
2017-05-17 14:45:37 +00:00
|
|
|
unsigned int m_num_layer_changes = 0;
|
|
|
|
// Tool change change counter for the output statistics.
|
|
|
|
unsigned int m_num_tool_changes = 0;
|
2017-05-16 11:45:28 +00:00
|
|
|
// Layer change counter in this layer. Counting up to m_max_color_changes.
|
2017-05-17 14:45:37 +00:00
|
|
|
unsigned int m_idx_tool_change_in_layer = 0;
|
2017-05-17 08:42:39 +00:00
|
|
|
// A fill-in direction (positive Y, negative Y) alternates with each layer.
|
2017-05-16 11:45:28 +00:00
|
|
|
wipe_shape m_current_shape = SHAPE_NORMAL;
|
2017-05-25 20:27:53 +00:00
|
|
|
unsigned int m_current_tool = 0;
|
2017-05-16 11:45:28 +00:00
|
|
|
// Current y position at the wipe tower.
|
|
|
|
float m_current_wipe_start_y = 0.f;
|
2017-09-12 13:55:38 +00:00
|
|
|
// How much to wipe the 1st extruder over the wipe tower at the 1st layer
|
|
|
|
// after the wipe tower brim has been extruded?
|
|
|
|
float m_initial_extra_wipe = 0.f;
|
2017-05-16 11:45:28 +00:00
|
|
|
|
|
|
|
struct box_coordinates
|
|
|
|
{
|
|
|
|
box_coordinates(float left, float bottom, float width, float height) :
|
|
|
|
ld(left , bottom ),
|
|
|
|
lu(left , bottom + height),
|
|
|
|
rd(left + width, bottom ),
|
|
|
|
ru(left + width, bottom + height) {}
|
|
|
|
box_coordinates(const xy &pos, float width, float height) : box_coordinates(pos.x, pos.y, width, height) {}
|
2017-05-17 14:45:37 +00:00
|
|
|
void translate(const xy &shift) {
|
|
|
|
ld += shift; lu += shift;
|
|
|
|
rd += shift; ru += shift;
|
|
|
|
}
|
|
|
|
void translate(const float dx, const float dy) { translate(xy(dx, dy)); }
|
2017-05-16 11:45:28 +00:00
|
|
|
void expand(const float offset) {
|
|
|
|
ld += xy(- offset, - offset);
|
|
|
|
lu += xy(- offset, offset);
|
|
|
|
rd += xy( offset, - offset);
|
|
|
|
ru += xy( offset, offset);
|
|
|
|
}
|
2017-05-17 14:45:37 +00:00
|
|
|
void expand(const float offset_x, const float offset_y) {
|
|
|
|
ld += xy(- offset_x, - offset_y);
|
|
|
|
lu += xy(- offset_x, offset_y);
|
|
|
|
rd += xy( offset_x, - offset_y);
|
|
|
|
ru += xy( offset_x, offset_y);
|
|
|
|
}
|
2017-05-16 11:45:28 +00:00
|
|
|
xy ld; // left down
|
|
|
|
xy lu; // left upper
|
|
|
|
xy ru; // right upper
|
|
|
|
xy rd; // right lower
|
|
|
|
};
|
|
|
|
|
|
|
|
// Returns gcode for wipe tower brim
|
|
|
|
// sideOnly -- set to false -- experimental, draw brim on sides of wipe tower
|
|
|
|
// offset -- set to 0 -- experimental, offset to replace brim in front / rear of wipe tower
|
2017-05-25 20:27:53 +00:00
|
|
|
ToolChangeResult toolchange_Brim(Purpose purpose, bool sideOnly = false, float y_offset = 0.f);
|
2017-05-16 11:45:28 +00:00
|
|
|
|
|
|
|
void toolchange_Unload(
|
|
|
|
PrusaMultiMaterial::Writer &writer,
|
|
|
|
const box_coordinates &cleaning_box,
|
2017-05-17 14:45:37 +00:00
|
|
|
const material_type current_material,
|
|
|
|
const int new_temperature);
|
2017-05-16 11:45:28 +00:00
|
|
|
|
|
|
|
void toolchange_Change(
|
|
|
|
PrusaMultiMaterial::Writer &writer,
|
2017-09-01 15:30:18 +00:00
|
|
|
const unsigned int new_tool,
|
2017-05-16 11:45:28 +00:00
|
|
|
material_type new_material);
|
|
|
|
|
|
|
|
void toolchange_Load(
|
|
|
|
PrusaMultiMaterial::Writer &writer,
|
|
|
|
const box_coordinates &cleaning_box);
|
|
|
|
|
|
|
|
void toolchange_Wipe(
|
|
|
|
PrusaMultiMaterial::Writer &writer,
|
2017-09-12 13:55:38 +00:00
|
|
|
const box_coordinates &cleaning_box,
|
|
|
|
bool skip_initial_y_move);
|
2017-05-16 11:45:28 +00:00
|
|
|
|
|
|
|
void toolchange_Perimeter();
|
|
|
|
};
|
|
|
|
|
|
|
|
}; // namespace Slic3r
|
|
|
|
|
|
|
|
#endif /* WipeTowerPrusaMM_hpp_ */
|