|
@@ -559,6 +559,7 @@ WipeTower::WipeTower(const PrintConfig& config, const PrintRegionConfig& default
|
|
|
m_extra_loading_move = float(config.extra_loading_move);
|
|
|
m_set_extruder_trimpot = config.high_current_on_filament_swap;
|
|
|
}
|
|
|
+
|
|
|
// Calculate where the priming lines should be - very naive test not detecting parallelograms etc.
|
|
|
const std::vector<Vec2d>& bed_points = config.bed_shape.values;
|
|
|
BoundingBoxf bb(bed_points);
|
|
@@ -625,6 +626,24 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config)
|
|
|
m_filpar[idx].ramming_step_multiplicator /= 100;
|
|
|
while (stream >> speed)
|
|
|
m_filpar[idx].ramming_speed.push_back(speed);
|
|
|
+ // ramming_speed now contains speeds to be used for every 0.25s piece of the ramming line.
|
|
|
+ // This allows to have the ramming flow variable. The 0.25s value is how it is saved in config
|
|
|
+ // and the same time step has to be used when the ramming is performed.
|
|
|
+ } else {
|
|
|
+ // We will use the same variables internally, but the correspondence to the configuration options will be different.
|
|
|
+ float vol = config.filament_multitool_ramming_volume.get_at(idx);
|
|
|
+ float flow = config.filament_multitool_ramming_flow.get_at(idx);
|
|
|
+ m_filpar[idx].multitool_ramming = config.filament_multitool_ramming.get_at(idx);
|
|
|
+ m_filpar[idx].ramming_line_width_multiplicator = 2.;
|
|
|
+ m_filpar[idx].ramming_step_multiplicator = 1.;
|
|
|
+
|
|
|
+ // Now the ramming speed vector. In this case it contains just one value (flow).
|
|
|
+ // The time is calculated and saved separately. This is here so that the MM ramming
|
|
|
+ // is not limited by the 0.25s granularity - it is not possible to create a SEMM-style
|
|
|
+ // ramming_speed vector that would respect both the volume and flow (because of
|
|
|
+ // rounding issues with small volumes and high flow).
|
|
|
+ m_filpar[idx].ramming_speed.push_back(flow);
|
|
|
+ m_filpar[idx].multitool_ramming_time = vol/flow;
|
|
|
}
|
|
|
|
|
|
m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later
|
|
@@ -839,12 +858,17 @@ void WipeTower::toolchange_Unload(
|
|
|
float remaining = xr - xl ; // keeps track of distance to the next turnaround
|
|
|
float e_done = 0; // measures E move done from each segment
|
|
|
|
|
|
- if (m_semm)
|
|
|
+ const bool do_ramming = m_semm || m_filpar[m_current_tool].multitool_ramming;
|
|
|
+
|
|
|
+ if (do_ramming) {
|
|
|
writer.travel(ramming_start_pos); // move to starting position
|
|
|
+ writer.disable_linear_advance();
|
|
|
+ }
|
|
|
else
|
|
|
writer.set_position(ramming_start_pos);
|
|
|
+
|
|
|
// if the ending point of the ram would end up in mid air, align it with the end of the wipe tower:
|
|
|
- if (m_semm && (m_layer_info > m_plan.begin() && m_layer_info < m_plan.end() && (m_layer_info-1!=m_plan.begin() || !m_adhesion ))) {
|
|
|
+ if (do_ramming && (m_layer_info > m_plan.begin() && m_layer_info < m_plan.end() && (m_layer_info-1!=m_plan.begin() || !m_adhesion ))) {
|
|
|
|
|
|
// this is y of the center of previous sparse infill border
|
|
|
float sparse_beginning_y = 0.f;
|
|
@@ -872,16 +896,18 @@ void WipeTower::toolchange_Unload(
|
|
|
sum_of_depths += tch.required_depth;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- writer.disable_linear_advance();
|
|
|
+
|
|
|
|
|
|
// now the ramming itself:
|
|
|
- while (m_semm && i < m_filpar[m_current_tool].ramming_speed.size())
|
|
|
+ while (do_ramming && i < m_filpar[m_current_tool].ramming_speed.size())
|
|
|
{
|
|
|
- const float x = volume_to_length(m_filpar[m_current_tool].ramming_speed[i] * 0.25f, line_width, m_layer_height);
|
|
|
- const float e = m_filpar[m_current_tool].ramming_speed[i] * 0.25f / filament_area(); // transform volume per sec to E move;
|
|
|
- const float dist = std::min(x - e_done, remaining); // distance to travel for either the next 0.25s, or to the next turnaround
|
|
|
- const float actual_time = dist/x * 0.25f;
|
|
|
+ // The time step is different for SEMM ramming and the MM ramming. See comments in set_extruder() for details.
|
|
|
+ const float time_step = m_semm ? 0.25f : m_filpar[m_current_tool].multitool_ramming_time;
|
|
|
+
|
|
|
+ const float x = volume_to_length(m_filpar[m_current_tool].ramming_speed[i] * time_step, line_width, m_layer_height);
|
|
|
+ const float e = m_filpar[m_current_tool].ramming_speed[i] * time_step / filament_area(); // transform volume per sec to E move;
|
|
|
+ const float dist = std::min(x - e_done, remaining); // distance to travel for either the next time_step, or to the next turnaround
|
|
|
+ const float actual_time = dist/x * time_step;
|
|
|
writer.ram(writer.x(), writer.x() + (m_left_to_right ? 1.f : -1.f) * dist, 0.f, 0.f, e * (dist / x), dist / (actual_time / 60.f));
|
|
|
remaining -= dist;
|
|
|
|
|
@@ -953,7 +979,7 @@ void WipeTower::toolchange_Unload(
|
|
|
// this is to align ramming and future wiping extrusions, so the future y-steps can be uniform from the start:
|
|
|
// the perimeter_width will later be subtracted, it is there to not load while moving over just extruded material
|
|
|
Vec2f pos = Vec2f(end_of_ramming.x(), end_of_ramming.y() + (y_step/m_extra_spacing-m_perimeter_width) / 2.f + m_perimeter_width);
|
|
|
- if (m_semm)
|
|
|
+ if (do_ramming)
|
|
|
writer.travel(pos, 2400.f);
|
|
|
else
|
|
|
writer.set_position(pos);
|
|
@@ -1040,8 +1066,9 @@ void WipeTower::toolchange_Wipe(
|
|
|
// the ordered volume, even if it means violating the box. This can later be removed and simply
|
|
|
// wipe until the end of the assigned area.
|
|
|
|
|
|
- float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height);
|
|
|
- float dy = m_extra_spacing*m_perimeter_width;
|
|
|
+ float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height) * (is_first_layer() ? m_extra_spacing : 1.f);
|
|
|
+ float dy = (is_first_layer() ? 1.f : m_extra_spacing) * m_perimeter_width; // Don't use the extra spacing for the first layer.
|
|
|
+ // All the calculations in all other places take the spacing into account for all the layers.
|
|
|
|
|
|
const float target_speed = is_first_layer() ? m_first_layer_speed * 60.f : m_infill_speed * 60.f;
|
|
|
float wipe_speed = 0.33f * target_speed;
|